1、Handler 内存泄漏的原因?
1、android 中所有的内存泄漏都是 生命周期不一致造成的。
2、内部类持有外部类的引用
3、handler 可以 发送 delay 消息。当 activity 已经销毁了,在调用 handleMessage 就会内存泄漏
Handler 持有外部的activity 而 message 会持有send 它的Handler,所以会造成连续持有
2、Activity中为什么可以 new Handler ? 子线程如何 new Handler?
因为 app 启动的时候,已经为我们调用了 Looper.prepare()【先调用】 和 Looper.loop() 【后调用】
需要在 子线程中也需要调用 prepare 和 looper.loop 方法 才可以new handler
【而且只能在 子线程 内去 new , 因为prepare和Looper.getLooper() 都是通过 Thread.currentThread() 去获取的】
3、在子线程中,我们如何处理 Looper.loop() 中的 死循环?当消息队列没有消息的时候,如何处理
调用 Looper 中的 Looper.myLooper().quitSafely(); 方法,会清空 MessageQueue 中的所有msg ,释放内存,释放线程
同时因为msg 是空的,所以Looper 会 自动调用 native 的一个方法(nativePollOnce《此方法其实是在messageQueue的next()方法中》),
自动挂起线程,在sendmsg的时候会在 唤醒线程。这样我们的线程才可以结束然后被唤醒,不然会一直阻塞在 Looper.loop() 中
注意:子线程必须要手动去操纵,quitSafely 方法,才可以讲 线程走完,Looper.loop() 后面的代码才可以执行完毕,不然会一直 阻塞 在Looper.loop()的死循环里面
注意:子线程必须要手动去操纵,quitSafely 方法,才可以将 线程走完,Looper.loop() 后面的代码才可以执行完毕,不然会一直 阻塞 在Looper.loop()的死循环里面。同时也起到了 释放线程的作用
4、在各个子线程中 sendmsg 的时候,主线程是如何处理的?
源码中 在 sendMessage 中会调用 MessageQueue中的enqueueMessage 方法
在这个方法中有synchronized 关键字。其中所有的 queue 都是一个 在 Looper的构造方法里面生成。
所以因为有关键字,多线程发送handler 消息的时候,时间就不准确了,
同样的在去消息的方法 next() 中也有 synchronized 关键字
5、Message 本身是 链表的结构 可以通过 obtain 去生成,new的话也可以。但是会增加链表长度。
其中 message 的本身会记录一个长度,最长是 50
网友评论