小心 DialogFragment 会造成内存泄漏

事情是这样的,我在项目里有个自定义的 Dialog 是继承 DialogFragment 实现的,接入 LeakCanary 后经常会提示我这个地方存在内存泄漏,定位的地方也有点奇怪,是一个布局控件上。

心想不应该啊,但既然报出来了,还是一探究竟。

内存泄漏

简单来说就是对象该销毁时没有被销毁回收,引用还被别的地方持有导致回收不掉,最后就变成了孤魂野鬼,达到一定程度就会导致 OOM 的问题了。

原因追踪

根据它报的位置我想难道是控件对象没被释放?于是我手动在 onDestoryView 里将控件 downLayout 赋值为 null,重试之后发现又报另外一个控件泄漏。显然问题不在这,这可能只是个表象。(得出这个推论花了我蛮长时间调试,经过多种猜测和尝试,大概定位在 DialogFragment 消失的时候,我复现问题的方式是,快速的打开销毁 DialogFragment)

回头在看看 LeakCanary 打出来的栈信息,指向的是 Message ???一开始我是不信的,打死都不信的,后来真香。表面上看 DialogFragment 的使用不会跟消息有什么关系啊,怎么会报 Message 的问题呢?看来需要我们看源码了。

DialogFragment 本质上是 Fragment 以 Dialog 的形式浮在 Activity 上展现,这个 Fragment 包含了一个 Dialog 对象,这个 Dialog 对象其实对我们是不可见的,因为我们不会直接操作它,重点就在这个 Dialog 上。

Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
        //省略部分......
        //Dialog 构造里会创建这个类,本质上是个 Handler 那肯定跟消息有关
        mListenersHandler = new ListenersHandler(this);
    }
//这个就是这个内部类,可以看到它对 Dialog 的持有是个弱引用,这其实是安全的,不会造成内存泄漏
private static final class ListenersHandler extends Handler {
        private final WeakReference<DialogInterface> mDialog;

        public ListenersHandler(Dialog dialog) {
            mDialog = new WeakReferenc
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值