首先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;
}
如果是强引用同样会产生上述情况引起内存泄漏
362

被折叠的 条评论
为什么被折叠?



