Handler 引起的内存泄露
2016-04-25 07:16
176 查看
先看一组简单的代码
当我们这样写在一个
意思说:
为什么会是这样呢?
了解一下
当Android程序第一次创建的时候,在主线程同时会创建一个
当一个
在
在什么地方引起了内存的泄露呢?再看看下面一段代码
当
解决办法,看下面一段代码
ok,结束
声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息
原文作者: 花_开_堪_折_枝
1 2 3 4 5 6 7 8 9 | public class SampleActivity extends Activity { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } } |
Activity中时,
Android Lint会提示我们这样一个 warning:
In Android, Handler classes should be static or leaks might occur.。
意思说:
在Android中,Handler 类应该是静态的否则可能发生泄漏。
为什么会是这样呢?
了解一下
Handler
当Android程序第一次创建的时候,在主线程同时会创建一个
Looper对象。
Looper实现了一个简单的消息队列,一个接着一个处理
Message对象。程序框架所有主要的事件(例如:屏幕上的点击时间,
Activity生命周期的方法等等)都包含在
Message对象中,然后添加到
Looper的消息队列中,一个一个处理。主线程的
Looper存在整个应用程序的生命周期内。
当一个
Handler对象在主线程中创建的时候,它会关联到
Looper的 message queue 。
Message添加到消息队列中的时候
Message会持有当前
Handler引用,当
Looper处理到当前消息的时候,会调用
Handler#handleMessage(Message).
在
java中,
no-static的内部类会 隐式的 持有当前类的一个引用。
static的类则没有。
在什么地方引起了内存的泄露呢?再看看下面一段代码
1 2 3 4 5 6 7 8 9 | public class SampleActivity extends Activity { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 发送一个10分钟后执行的一个消息 mHandler.postDelayed(new Runnable() { @Override public void run() { } }, 600000); // 结束当前的Activity finish(); } } |
Activity结束后,在 Message queue 处理这个
Message之前,它会持续存活着。这个
Message持有
Handler的引用,而
Handler有持有
Activity(SampleActivity)的引用,这个
Activity所有的资源,在这个消息处理之前都不能也不会被回收,所以发生了内存泄露。
解决办法,看下面一段代码
1 2 3 4 5 6 7 8 9 | public class SampleActivity extends Activity { /** * 使用静态的内部类,不会持有当前对象的引用 */ private static class MyHandler extends Handler { private final WeakReference<SampleActivity> mActivity; public MyHandler(SampleActivity activity) { mActivity = new WeakReference<SampleActivity>(activity); } @Override public void handleMessage(Message msg) { SampleActivity activity = mActivity.get(); if (activity != null) { // ... } } } private final MyHandler mHandler = new MyHandler(this); /** * 使用静态的内部类,不会持有当前对象的引用 */ private static final Runnable sRunnable = new Runnable() { @Override public void run() { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 发送一个10分钟后执行的一个消息 mHandler.postDelayed(sRunnable, 600000); // 结束 finish(); } } |
声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息
原文作者: 花_开_堪_折_枝
相关文章推荐
- 这样读源码,不牛X也难
- 每日站立会议——20160425
- Unity学习笔记五 - Survival Shooter Tutorial
- javascript入门(一)
- VMware Player安装centos
- ossec开源ids
- 第一次冲刺阶段第七天
- 画图函数——点,线,矩形等等
- 大型分布式C++框架《四:netio之buffer管理器 下》
- 上周热点回顾(4.18-4.24)
- 站立会议07
- css的继承
- 第一冲刺阶段——个人工作总结08
- 第一冲刺阶段——站立会议第八天4月25日
- 数据结构1
- Swift快速入门之枚举与结构
- python特性、属性以及私有化
- Detailed Singleton pattern
- U3D添加按钮相应事件
- 220. Contains Duplicate III