Handler作为Activity的内部类所引起的内存泄露问题
来源:互联网 发布:2016淘宝618报名入口 编辑:程序博客网 时间:2024/04/26 05:10
前天参加某公司的面试,被问到一个关于Handler作为Activity的内部类所引起的内存泄露的问题。虽然当时答上来了,但是还是想在这里记录一下。
问题总共分为两问:
1、Handler作为Activity的内部类来使用,会导致什么问题。
第一问很容易答上来,非静态的内部类会持有外部类实例的引用。因此,当通过Handler.post(Runnable r)或者sendMessage(Message msg)一个任务到MessageQueue中去时,会因为Message持有Handler,而Handler持有Activity,从而形成Message-----Handler-----Activity的引用链。这样,当Avtivity的生命周期结束,而消息还没有来得及处理时,由于上述引用链的存在而导致Activity不能及时回收,从而会引起内存泄露。
2、如果存在内存泄露,请说出它的完整引用链。
当时,听到第二问的时候,一下子没有反应过来,自己不是已经在第一个问题的回答中阐述了吗?后来,和面试官确认了一下,要求是要说出导致内存泄露的完整引用链。于是,不得不将Thread、Looper、MessageQueue、Message、Handler之间的关系在脑子里迅速地过一遍。
我们知道,对于一个Handler来说,必须要有一个Looper与之相关联,而Looper是要运行在线程中的。由于主线程的Looper在ActivityThreadhttp://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/app/ActivityThread.java 的main()方法中就已经创建了,因此在主线程中创建Hanlder,并且我们也希望经过该Handler所发送的消息在主线程得到处理时,那么就不必再显式地为其指定Looper了。否则,我们需要为其显式地去指定一个Looper。要得到一个带Looper的线程,我们可以自己去创建,也可以直接使用Android为我们提供的http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/os/HandlerThread.java。该类继承至Thread,并实现了run()方法, 在run()方法中实现了对成员变量mLooper的初始化,并通过Looper.loop()方法让线程进入一个死循环,以响应并处理投递到消息队列中的消息。既然已经有了现成的带Looper的线程,那么我们就可以建立一个工作在非主线程的Handler了:HandlerThread workerThread = new HandlerThread("worker"); Handler woker = new Handler(workerThread.getLooper())。通过上面的分析,可以知道:所谓地Handler工作在哪个线程, 说的就是与Handler关联的Looper的loop()方法工作在哪个线程,也就是创建并持有Looper的那个线程。于是,Thread-----Looper之间存在引用链关系。
我们知道,消息是通过Handler发送到消息队列中去的,现在Handler有了与之关联的Looper,但是却还没有接收消息的MessageQueue。但是,通过查看Looper类的源码 http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/os/Looper.java 可以知道其内部有一个叫做mQueue的MessageQueue类型的成员变量,这个变量的初始化时机是在Looper被构造的时候。因此,其实在将Looper与Handler相关联时,就已经附带了一个MessageQueue给Handler了。于是,Looper-----MessageQueue之间存在引用链。
最后,结合上面的分析,就可以得到完整的引用链Thread----Looper---MessageQueue---Message---Handler---Activity。
1 0
- Handler作为Activity的内部类所引起的内存泄露问题
- Handler声明成内部类所引起的内存泄露问题
- Handler或Runnable作为非静态内部类,引发的内存泄露问题
- Handler&内部类导致的内存泄露问题
- Handler当做内部类,导致内存泄露的问题
- Handler当做内部类,导致内存泄露的问题
- Handler 当做内部类,导致内存泄露的问题
- 匿名内部类引起的内存泄露——Handler和Thread
- Handler引起的内存泄露问题
- Handler引起的内存泄露问题
- TextWatcher引起activity内存泄露的问题
- Handler 引起的内存泄露
- Handler 引起的内存泄露
- Handler 引起的内存泄露
- Handler 引起的内存泄露
- Handler 引起的内存泄露
- Handler引起的内存泄露
- Handler 引起的内存泄露
- CF 135 DIV2 B Special Offer! Super Price 999 Bourles! 思维
- rtems源码贡献步骤
- Android中关于menu(菜单)的创建与使用
- Android入门之——百度地图开发(一)
- Oracle监听日志频繁报unknown connect data 12537错误诊断
- Handler作为Activity的内部类所引起的内存泄露问题
- Gson对字符串null的字段转换为空字符串输出
- 【第6题】360校园招聘2015届技术类笔试题
- ccf/201409-3 /字符串匹配---java
- 紫书搜索 习题7-3 UVA
- android中fragment出现replace方法参数不匹配
- 函数模板---上
- java 观察者模式
- REPLACE INTO 和 INSERT INTO ... ON DUPLICATE KEY UPDATE SET ...