DialogFragment引起的内存泄露

本文字数:2830

预计阅读时间:9分钟

一、简介

DialogFragment是Android3.0之后引入的一种特殊的Fragment,官方建议使用DialogFragment代替Dialog或者AllertDialog来实现弹框的功能,因为它可以更好的管理Dialog的生命周期以及可以更好复用。

二、使用中遇到内存泄露

在使用过程中,由于业务需要对DialogFragment的dismiss事件进行了监听,在DialogFragment展示与消失的时候,经常会出现LeakCanary检测的内存泄露问题。查看LeakCanary的内存泄露引用链如下图所示:

这里只贴出了一张图,LeakCanary每次报出来的引用链并不完全相同,图上中显示的是RxJava的ThreadHandler,有的则显示的是高德地图的ThreadHandler(amapLocManagerThread),由此猜测这里并不是主线程的ThreadHandler引起的内存泄露,而是第三方库中的ThreadHandler引起的内存泄露。

但总的来说都是HandlerThread中处理的Message引用了NormalTitleBgDialog(DialogFragment)不能被释放。下面具体分析一下出现这个问题的原因。

三、原因分析

那么Message是怎么引用到DialogFragment的呢?在DialogFragment中搜索一下Message一无所获。DialogFragment实际是Dialog的封装,在Dialog中搜索Message试试,果然发现Dialog的Cancle和Dismiss都是通过Handler进行操作的,从这里入手分析一下内存泄露的原因:

  1. DialogFragment中的onActivityCreated Cancle和Dismiss的监听传入的是DialogFragment实现的两个接口:DialogInterface.OnCancelListener, DialogInterface.OnDismissListener

 @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mDialog.setOnCancelListener(this);
        mDialog.setOnDismissListener(this);
    }
  1. setOnDismissListener 这里会通过mListenerHandler获取到一个mDismissMessage对象。

    public void setOnDismissListener(@Nullable OnDismissListener listener) {
        if (mCancelAndDismissTaken != null) {
            throw new IllegalStateException(
                    "OnDismissListener is already taken by "
                    + mCancelAndDismissTaken + " and can not be replaced.");
        }
        if (listener != null) {
            mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener);
        } else {
            mDismissMessage = null;
        }
    }

   public void setOnCancelListener(@Nullable OnCancelListener listener) {
        if (mCancelAndDismissTaken != null) {
            throw new IllegalStateException(
                    "OnCancelListener is already taken by "
                    + mCancelAndDismi
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值