Android Handler造成的内存泄漏的分析j
来源:互联网 发布:淘宝的二级词怎么定义 编辑:程序博客网 时间:2024/05/18 18:14
在分析之前先补充下java的基本知识,与本文的分析有着重大的联系:在java中,非静态(匿名)内部类会默认隐性引用外部类对象,而静态的内部类不会引用外部类对象,注意与静态变量的区别,静态变量是会引用外部类变量的
在Android中,Handler也是造成内存泄露的一个重要的源头,主要是因为Handler属于TLS(Thread Local Storage)变量,生命周期和Activity是不一致的,因此Handler引用Activity会存在内 存泄露。会造成内存泄露的示例代码:
public class HandlerActivity extends Activity { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler.sendMessageDelayed(Message.obtain(), 60000); //just finish this activity finish(); } }
在上述代码中,handler所引用的外部类是activity,当activity finish之后,延时消息会继续存在主线程的消息队列中一分钟,然后再处理消息。因为消息引用了activity中的handler(消息中的target变量指向了该handler,即mHandler),而mHandler作为非静态(匿名)内部类,又会默认隐形的引用外部类变量,即对应代码中的activity。这些引用对象会保持到该消息被处理完,这样就导致了该activity对象无法被回收,从而导致了上面说的activity泄露。那么上述代码该如何修改呢?可以使用显示的引用,如使用静态内部类(示例代码中还使用了弱引用WeakReference):
public class HandlerActivity2 extends Activity { private static final int MESSAGE_1 = 1; private static final int MESSAGE_2 = 2; private static final int MESSAGE_3 = 3; private final Handler mHandler = new MyHandler(this); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler.sendMessageDelayed(Message.obtain(), 60000); // just finish this activity finish(); } public void todo() { }; private static class MyHandler extends Handler { private final WeakReference<HandlerActivity2> mActivity; public MyHandler(HandlerActivity2 activity) { mActivity = new WeakReference<HandlerActivity2>(activity); } @Override public void handleMessage(Message msg) { System.out.println(msg); if (mActivity.get() == null) { return; } mActivity.get().todo(); } }
当然,也可以将MyHandler写成一个独立的外部类。但是上面的代码还不完美,因为当activity finish之后,handler对象还是在message中排队,还是会处理消息。实际上在一般的情况下,activity finish之后,已经没有必要对消息继续处理了,那么该如何优化呢?解决方案也很简单,在activity onStop或者onDestroy的时候,取消掉该handler对象的message和runnable,如这些方法removeCallbacks(Runnable r)和removeMessages(int what),当然也可以简单粗暴一点:
@Override public void onDestroy() { // If null, all callbacks and messages will be removed. mHandler.removeCallbacksAndMessages(null); }
0 0
- Android Handler造成的内存泄漏的分析j
- Android内存泄漏(Handler造成的内存泄漏(一))
- Android内存泄漏(Handler造成的内存泄漏(二))
- Android Handler造成内存泄露的分析和解决
- Android使用Handler造成内存泄露的分析及解决方法
- Android使用Handler造成内存泄露的分析及解决方法
- Android中使用Handler造成内存泄露的分析总结
- Android使用Handler造成内存泄露的分析及解决方法
- Android使用Handler造成内存泄露的分析及解决方法
- Andorid中Handler造成的内存泄漏浅析与处理
- 如何避免使用Handler造成的内存泄漏
- Android开发-Handler引起的内存泄漏-实验、分析、总结。
- Android开发-Handler引起的内存泄漏-实验、分析、总结。
- Android handler 引起的内存泄漏
- Android handler导致的内存泄漏
- Android Handler导致内存泄漏的解决方案
- Android handler的内存泄漏问题
- IBOutlet造成的内存泄漏
- PES,TS,PS,RTP等流的打包格式解析之TS流
- lua截取中英文混合字符串
- KVO模式具体运用细节
- php命令行运行类中的方法
- UVA, 374 Big Mod
- Android Handler造成的内存泄漏的分析j
- 1018. Public Bike Management (30)
- Python3网络爬虫(三):Python3使用Cookie-模拟登陆获取妹子联系方式
- python 基本数据类型梳理
- Netty从没听过到入门 -- 服务器端详解
- SQL质疑ch处理
- mysql 对插入重复记录的三种方法,ignore,replace,on duplicate key update
- 【费马小定理求逆元】51nod 1119 LightOJ 1067
- Python闭包之二