BottomSheetDialogFragment、DialogFragment内存泄漏记录

项目开发中大多会使用leakcanary内存泄漏检测工具检测内存泄漏,leakcanary检测会发现BottomSheetDialogFragment、DialogFragment有内存泄漏情况。如果还不清楚为什么出现内存泄漏,请移步Google或百度;这里不详细描述为什么内存泄露了,默认你已经知道了为什么BottomSheetDialogFragment、DialogFragment有内存泄漏情况。(如有问题欢迎指正!)

解决步骤:(已真机测试)

1、新建一个DialogInterfaceProxy类,用来持有Dialog中DialogInterface接口下的OnCancelListener、OnDismissListener、OnShowListener真正的回调,代码如下:

public class DialogInterfaceProxy {
    public static DialogInterface.OnCancelListener proxy(DialogInterface.OnCancelListener onCancelListener) {
        return new ProxyOnCancelListener(onCancelListener);
    }

    public static DialogInterface.OnDismissListener proxy(DialogInterface.OnDismissListener onDismissListener) {
        return new ProxyOnDismissListener(onDismissListener);
    }

    public static DialogInterface.OnShowListener proxy(DialogInterface.OnShowListener onShowListener) {
        return new ProxyOnShowListener(onShowListener);
    }

    /**
     * 使用弱引用持有Dialog真正的DialogInterface.OnCancelListener,
     * <p>
     * 即使Message.obj未被正常释放,最终它持有的也只是ProxyOnCancelListener的一个空壳实例
     */
    public static class ProxyOnCancelListener implements DialogInterface.OnCancelListener {
        private WeakReference<DialogInterface.OnCancelListener> mProxyRef;

        public ProxyOnCancelListener(DialogInterface.OnCancelListener onCancelListener) {
            mProxyRef = new WeakReference<>(onCancelListener);
        }

        @Override
        public void onCancel(DialogInterface dialog) {
            DialogInterface.OnCancelListener onCancelListener = mProxyRef.get();
            if (onCancelListener != null) {
                onCancelListener.onCancel(dialog);
            }
        }
    }

    /**
     * 使用弱引用持有Dialog真正的DialogInterface.OnDismissListener,
     * <p>
     * 即使Message.obj未被正常释放,最终它持有的也只是ProxyOnDismissListener的一个空壳实例
     */
    public static class ProxyOnDismissListener implements DialogInterface.OnDismissListener {
        private WeakReference<DialogInterface.OnDismissListener> mProxyRef;

        public ProxyOnDismissListener(DialogInterface.OnDismissListener onDismissListener) {
            mProxyRef = new WeakReference<>(onDismissListener);
        }

        @Override
        public void onDismiss(DialogInterface dialog) {
            DialogInterface.OnDismissListener onDismissListener = mProxyRef.get();
            if (onDismissListener != null) {
                onDismissListener.onDismiss(dialog);
            }
        }
    }

    /**
     * 使用弱引用持有Dialog真正的DialogInterface.OnShowListener,
     * <p>
     * 即使Message.obj未被正常释放,最终它持有的也只是ProxyOnShowListener的一个空壳实例
     */
    public static class ProxyOnShowListener implements DialogInterface.OnShowListener {
        private WeakReference<DialogInterface.OnShowListener> mProxyRef;

        public ProxyOnShowListener(DialogInterface.OnShowListener onShowListener) {
            mProxyRef = new WeakReference<>(onShowListener);
        }

        @Override
        public void onShow(DialogInterface dialog) {
            DialogInterface.OnShowListener onShowListener = mProxyRef.get();
            if (onShowListener != null) {
                onShowListener.onShow(dialog);
            }
        }
    }
}

2、新建ProxyBottomSheetDialog继承BottomSheetDialog,将其中super.setOnCancelListener、super.setOnDismissListener、super.setOnShowListener参数使用DialogInterfaceProxy类包裹起来,代码如下:

public class ProxyBottomSheetDialog extends BottomSheetDialog {

    public ProxyBottomSheetDialog(@NonNull Context context) {
        super(context);
    }

    public ProxyBottomSheetDialog(@NonNull Context context, int theme) {
        super(context, theme);
    }

    protected ProxyBottomSheetDialog(@NonNull Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    @Override
    public void setOnCancelListener(@Nullable OnCancelListener listener) {
        super.setOnCancelListener(DialogInterfaceProxy.proxy(listener));
    }

    @Override
    public void setOnDismissListener(@Nullable OnDismissListener listener) {
        super.setOnDismissListener(DialogInterfaceProxy.proxy(listener));
    }

    @Override
    public void setOnShowListener(@Nullable OnShowListener listener) {
        super.setOnShowListener(DialogInterfaceProxy.proxy(listener));
    }
}

3、新建ProxyBottomSheetDialogFragment继承BottomSheetDialogFragment,重写onCreateDialog方法,该方法中改为自定义的ProxyBottomSheetDialog,代码如下:

public class ProxyBottomSheetDialogFragment extends BottomSheetDialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        if (getContext() == null) {
            return super.onCreateDialog(savedInstanceState);
        }
        return new ProxyBottomSheetDialog(getContext(), getTheme());
    }
}

4、DialogFragment处理同上2、3步骤!!!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值