lopper ThreadLocal handler造成内存泄漏的原因

首先looper.prepare()方法会判断是否只有一个looper 如果有多个会报错 ,然后构建出一个looper
在这里插入图片描述
怎么保证一个线程只持有一个looper?
在这里插入图片描述
每个Thread对象持有一个ThreadLocalMap对象(很像hashMap) 再看上面sThreadLocal.set方法
在这里插入图片描述直接获取ThreadLocalMap对象 进行存放 key是线程 value是looper。这也解释了上面通过sThreadLocal.get()方法去进行是否looper已存在的判断。

looper.loop方法内是一个for(;;)的死循环 不过在没有消息处理的时候会进行阻塞 当有消息来时就不断取出MessageQueue中的消息 并将取出来的消息分给对应的Handler处理

ThreadLocal主要作用就是存放looper以及供Thread去取出lopper

handler造成内存泄漏的原因:

内存泄漏的本质:长生命周期对象持有了短生命周期的对象 导致短生命周期的对象不能被回收
首先app最长的生命周期的对象是 : 主线程
主线程有对应的looper以及messageQueue 这些是跟主线程绑定的不会被回收。
当子线程的handler发送一个msg时 msg.target会被赋值成handler存放在messageQueue中
这样handler就与主线程有了关联
在这里插入图片描述

(都是handler内的方法 this就代表handler)
在这里插入图片描述
然后由于handler被相关的(activity)类所持有 所以该类无法被回收

那么避免内存泄漏最简单的措施 就是给handler加static 使其变成静态 这样就与类的对象解绑了 不会影响对象的回收
当然在面对需要activity对象的成员时比如更新ui 此时需要使用弱引用

比如 private WeakReference<***Activity> weakReference;
在handler创造一个构造方法传入对应activity

public MyHandler(HandlerOOMActivity activity) {
            weakReference = new WeakReference<>(activity);
            this.activity = activity;
        }

如果是强引用同样会产生上述情况引起内存泄漏

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值