Leakcanary: DialogFragment RefWatcher was watching this and Fragment#mFragmentManager is null and Fragment#mFragmentManager is null

Created on 15 Jul 2019  ·  4Comments  ·  Source: square/leakcanary

com.samluys.devdemo.ShortVideoDialog Leaking: YES (RefWatcher was watching this and Fragment#mFragmentManager is null and Fragment#mFragmentManager is null) , retainedHeapSize=null), NoPathToInstance(referenceKey=a1489560-f893-4e64-bd77-7e6759fa5295, referenceName=, instanceClassName=com.samluys.devdemo.ShortVideoDialog, watchDurationMillis=6482, retainedDurationMillis=1480), NoPathToInstance(referenceKey=9af8a7ee-7c0a-4b56-8d8e-4b79ccdcd34c, referenceName=, instanceClassName=com.samluys.devdemo.ShortVideoDialog, watchDurationMillis=7420, retainedDurationMillis=2418), NoPathToInstance(referenceKey=dceb6d28-27fe-4635-a25d-32c3cf2d93c8, referenceName=, instanceClassName=com.samluys.devdemo.ShortVideoDialog, watchDurationMillis=10117, retainedDurationMillis=5116), NoPathToInstance(referenceKey=8587a630-1aec-47f9-bd21-d7628154764a, referenceName=, instanceClassName=com.samluys.devdemo.ShortVideoDialog, watchDurationMillis=11357, retainedDurationMillis=6356)])

public class ShortVideoDialog extends DialogFragment implements View.OnClickListener {

    private TextView mTVVideo;
    private ImageView mIVClose;
    private TextView mTVEditer;
    private TextView mTVPicture;
    private int mFrom;
    private FragmentManager manager;

    public static ShortVideoDialog newInstance(int from) {
        ShortVideoDialog dialog = new ShortVideoDialog();
        Bundle bundle = new Bundle();
        bundle.putInt("VIDEO_DIALOG_FROM", from);
        dialog.setArguments(bundle);
        return dialog;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        final Dialog dialog = new Dialog(getActivity(), R.style.BottomDialog);

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.dialog_short_video);
        dialog.setCanceledOnTouchOutside(true);

        mTVVideo = dialog.findViewById(R.id.tv_record);
        mTVEditer = dialog.findViewById(R.id.tv_editer);
        mTVPicture = dialog.findViewById(R.id.tv_picture);
        mIVClose = dialog.findViewById(R.id.iv_close);

        mTVVideo.setOnClickListener(this);
        mTVEditer.setOnClickListener(this);
        mTVPicture.setOnClickListener(this);
        mIVClose.setOnClickListener(this);

        return dialog;
    }

    @Override
    public void onStart() {
        super.onStart();


        try {
            // 设置宽度为屏宽, 靠近屏幕底部。
            Window window = getDialog().getWindow();
            WindowManager.LayoutParams lp = window.getAttributes();
            lp.gravity = Gravity.BOTTOM;
            lp.width = WindowManager.LayoutParams.MATCH_PARENT; // 宽度持平
            window.setAttributes(lp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_record:
                dismissDialog();
                break;
            case R.id.tv_editer:
                dismissDialog();
                break;
            case R.id.tv_picture:
                dismissDialog();
                break;
            case R.id.iv_close:
                dismissDialog();
                break;
        }
    }

    public void showDialog(FragmentManager fragmentManager, String tag) {
        manager = fragmentManager;
        if (!isAdded()) {
            show(fragmentManager, tag);
        }

    }

    public void dismissDialog() {
//        if (ShortVideoDialog.this.isAdded()) {
//            ShortVideoDialog.this.dismiss();
//            if (getDialog() != null) {
//                getDialog().dismiss();
//            }
//        }
        dismiss();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        manager = null;
        if (getDialog() != null) {
            getDialog().dismiss();
        }
    }
}```

in activity

```java

findViewById(R.id.btn_rx).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mShortDialog == null) {
                    mShortDialog = ShortVideoDialog.newInstance(1);
                }

                mShortDialog.showDialog(getSupportFragmentManager(), "ShortVideoDialog");
            }
        });
Close immediately

Most helpful comment

@ltym2016 did you solve this ?

As stated by @bsia, in the fundamentals you can get the the reason and the solution (very clear tbh). If none of you guys want to go there, basically what you need to do is "[...] to null out your references to the views in onDestroyView as that's the sign that the view is no longer being used by the Fragment system and it can be safely garbage collected if it wasn't for your continued reference to the View".

All 4 comments

This issue tracker is not for help with memory leaks detected by LeakCanary in your own app.

To fix a leak:

For those who end up in this page looking for info, this is the updated fundamentals link:
https://square.github.io/leakcanary/fundamentals/

@ltym2016 did you solve this ?

@ltym2016 did you solve this ?

As stated by @bsia, in the fundamentals you can get the the reason and the solution (very clear tbh). If none of you guys want to go there, basically what you need to do is "[...] to null out your references to the views in onDestroyView as that's the sign that the view is no longer being used by the Fragment system and it can be safely garbage collected if it wasn't for your continued reference to the View".

Was this page helpful?
0 / 5 - 0 ratings