Context内存泄露:Handler&内部类
来源:互联网 发布:淘宝网店贷款 编辑:程序博客网 时间:2024/06/06 20:53
之前代码中,我经常会去使用Thread去处理耗时操作,再用Handler去返回到主线程,后面涉及到内存泄露,才知道这里面存在了很大的隐患–内存泄露。
之前,一直以为Context发生内存泄露的几率很小,就不以为意。奈何当Android Lint给出下面的警告时,我收起小觑之心。
In Android, Handler classes should be static or leaks might occur.
这是我的代码:
public class WallPaperActivity extends Activity { //.... private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } //....}
Android Lint给出这句话的意思,就是:定义的Handler类应该是一个静态类,不然可能会导致内存泄露。
为什么Hanlder会导致内存泄露呢?
让我们看看代码里做了什么事:
public class WallPaperActivity extends Activity { //... private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... imageview.setImagebitmap(bitmap); } }}
这边主要进行的是后台线程拉取网络图片的一个操作,然后在主线程中进行更新界面。
这里,我们要知道:当一个Android应用程序第一次启动时,Android框架为应用程序的主线程创建一个Looper对象。一个Looper实现了一个简单的消息队列,在一个循环中处理Message对象。所有主要的应用程序框架事件(如活动生命周期方法调用,单击按钮,等等)都包含在Message对象,它被添加到Looper的消息队列然后一个个被处理。主线程的Looper在应用程序的整个生命周期中存在。而当一个Handle在主线程被实例化,它就被关联到Looper的消息队列。被发送到消息队列的消息会持有一个Handler的引用,以便Android框架可以在Looper最终处理这个消息的时候,调用Handler.handleMessage(Message)。在java中,非静态的内部类和匿名类会隐式的持有一个当前外部类的引用。然而,静态内部类不会。(来自译文)
所以,上面代码中创建handler时,其实该对象已经隐式持有WallPaperActivity的引用了,由于后台在下载拉取图片,可能会很快,可能慢的跟狗一样,这时,在界面关闭之前,加载完图片并显示到界面上,即hanlder处理消息完毕,那自然万事大吉。可是网络不好时,图片下载一半时,Activity关闭,这时,因为线程没执行完,线程中Handler持有WallPaperActivity引用,导致了该Activity无法被回收,这就是泄露的来源。
查找了网络大神等对此的解决方案,总共有两个:
1.根据界面需要去对包含Hanlder的线程进行限制:在关闭Activity(onDestroy())之前停掉线程。显然这是一个方法,不过对我不适合,毕竟我希望图片最好可以下下来的。
2.声明Handler类为静态类:
static class MyHandler extends Handler { WeakReference<WallPaperActivity> mActivity; MyHandler(WallPaperActivity activity) { mActivity = new WeakReference<WallPaperActivity>(activity); } @Override public void handleMessage(Message msg) { WallPaperActivity theActivity = mActivity.get(); if(theActivity != null){ //... } } } MyHandler ttsHandler = new MyHandler(this);
这里就是按照Android Lint把handler类定义为静态,然后通过WeakReference(弱引用)来保持外部Activity对象。
显然,这后面一种,是我需要的!
- Context内存泄露:Handler&内部类
- 什么导致了Context泄露:Handler&内部类
- 什么导致了Context泄露:Handler&内部类
- 【译】什么导致了Context泄露:Handler&内部类
- 什么导致了Context泄露:Handler&内部类
- 什么导致了Context泄露:Handler&内部类
- 什么导致了Context泄露:Handler&内部类
- Android:Handler,内部类导致的可能内存泄露
- Handler&内部类导致的内存泄露问题
- Handler当做内部类,导致内存泄露的问题
- 使Handler内部类导致内存泄露的解决方法
- Handler当做内部类,导致内存泄露的问题
- 非静态内部类Handler类引起内存泄露
- Handler 当做内部类,导致内存泄露的问题
- Android handler的Context内存泄露
- 匿名内部类引起的内存泄露——Handler和Thread
- Handler作为Activity的内部类所引起的内存泄露问题
- Handler声明成内部类所引起的内存泄露问题
- hdu 5339 Untitled(枚举 || DFS)
- 关于安卓集成支付宝的问题jar包冲突
- BootStrap页头和缩略图
- Codeforces Round #313 Equivalent Strings(递归)
- POJ3264Balanced Lineup(经典线段树)
- Context内存泄露:Handler&内部类
- uva 10125 - Sumsets
- OpenGL错误和性能Tips
- 关于jdk的报错问题 It is indirectly referenced from required .class files
- 火狐浏览器安装firebug失败的解决方法
- 线段树模板
- 关于C语言数组利用指针排序的问题
- nm 目标文件格式分析
- struts 框架