Andorid中Handler造成的内存泄漏浅析与处理
来源:互联网 发布:win7怎样设置网络连接 编辑:程序博客网 时间:2024/06/05 09:33
Andorid中Handler造成的内存泄漏浅析与处理
概述:
Handler机制是Android中提供的一个异步回调机制,我们可以在完成一个耗时任务后作出相应通知。
每一个消息都需要被指定的Handler处理,通过Handler创建消息便可以完成此功能。Android消息机制中 引入了消息池。Handler创建消息时首先查询消息池中是否有消息存在,如果有直接从消息池中取得,如果没有则重新初始化一个消息实例。使用消息池的好 处是:消息不被使用时,并不作为垃圾回收,而是放入消息池,可供下次Handler创建消息时使用。消息池提高了消息对象的复用,减少系统垃圾回收的次数。但是,正是这个机制,当Activity被销毁时,消息队列中有信息尚未被处理,容易引起内存泄漏。
正文:
下面我们举个例子:
1. 新建一个工程, 配置好leakCanary内存泄漏检测环境。(leakCanary:第三方Android和Java的内存泄露检测库)
2. 布局好UI 。(界面布局仅一个button, activity_main.xml文件中加个Button即可,Button 的ID为send_btn).
3. 在MainActivity中添加如下代码:
在平常项目开发中,我们经常这样使用handler类,在一个界面中加载数据loadData,加载数据完成后,发送Message,然后在在Handler的handlerMessage()中去处理我们的消息。
运行代码,我们做如下操作:
1. 点击按钮,在20秒内点击手机返回键,关闭MainActivity;
2. 等待10秒左右,会出现以下结果,此时,LeakCanary提示内存泄漏:
分析:
由于mhandler是Handler的匿名内部类的实例,所以它持有外部类Activity的引用,我们知道消息队列是在一个Looper线程中不断轮询处理消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,那么当这个Activity退出时,消息队列中还有未处理的消息或者正在处理消息,将导致该Activity的内存资源无法及时回收,引发内存泄漏。
解决方法:
使用静态内部类,将上面的代码改一下:
修改代码后运行,重复上面相同的操作,LeakCanary并没有报出内存泄漏。但是在开发中,在我们平时使用handlerMessage处理消息时,很多时候需要去使用外部类MainActivity的函数,比如我们需要更新MainActivity的UI 。
Handler使用方式升级版: 使用弱引用 -解决静态内部类访问外部类
名词解释:弱引用-----可以被JAVA 虚拟机顺利垃圾回收的一种引用方式
代码流程如下:
1. 修改一下我们刚才例子中的UI :在MainActity的布局文件 activity_main.xml中添加一个TextView ,并且在MainActity的oncreate找到并初始化它。
代码和效果示意如下:
2. 我们在handlerMessage中,给TextView设置值,请注意红色方框内的弱引用使用方式:
分析上面的做法:
创建一个静态Handler内部类,然后对Handler持有的外部对象使用弱引用,这样在回收时也可以回收Handler持有的对象,解决了我们内存泄漏以及访问外部对象的问题。
但是,这样子还不够完美: 我们退出MainActivity后,Looper线程的消息队列中还是可能会有待处理的消息,啥意思呢?就是我们MainActivity退出后,消息队列里还有消息,即我们的例子中,20秒后,还收到消息队列中的消息。
更完美的做法:我们应该在Activity关闭的时候,移除消息队列中的消息。
总结:在我们以后开发中使用handler时,就可以使用静态类和弱引用,这样可以避免内存泄漏现象,达到内存优化的目的。
- Andorid中Handler造成的内存泄漏浅析与处理
- Android-浅析Android消息处理机制使用不当造成的内存泄漏
- Android Handler造成的内存泄漏的分析j
- 如何避免使用Handler造成的内存泄漏
- Handler可能造成内存泄漏(四)
- Android内存泄漏(Handler造成的内存泄漏(一))
- Android内存泄漏(Handler造成的内存泄漏(二))
- 浅析Handler引起的内存泄漏及解决方法
- 浅析Handler引起的内存泄漏及解决方法
- 浅析Handler引起的内存泄漏及解决方法
- Android内存泄漏(线程造成的内存泄漏与资源未关闭造成的内存泄漏)
- IBOutlet造成的内存泄漏
- cdbexception造成的内存泄漏
- MVP造成的内存泄漏
- 解决IE6中元素插入顺序造成的内存泄漏
- 如何防止activity的双重引用和Handler等造成内存泄漏
- 内存优化-内存泄漏处理handler
- Android中使用Handler造成内存泄露的分析总结
- 【noip】Mayan游戏 搜索
- Jmeter使用奇葩问题集锦
- LINUX IO 程序编程
- idea设置注释作者信息
- 使用setInterval()方法输出一个计时器
- Andorid中Handler造成的内存泄漏浅析与处理
- C# 关于NULL 可空值类型 ? 和空接操作符??
- webservices应用----查询航班
- 文件上传和文件下载
- 二叉树的遍历(2)--先序遍历,中序遍历,后序遍历(非递归)
- C++ 虚函数表解析
- javaScript知识点----如何跳出多重循环break,continue
- 小车
- linux内核的并发与竞态