[Android 内存泄漏] 了解 Handler leak
来源:互联网 发布:淘宝如何使用电子面单 编辑:程序博客网 时间:2024/06/07 02:17
基本的原理就是,内部类 ( 包括匿名内部类 ) 不管有无调用,实际上会持有外部类对象的引用。比如下面的代码 C 类可以取得外部类的变量值。
public class InnerTest { private String mContent = "hi"; class B { private String mContent = "hi, B"; class C { public void test() { System.out.println(InnerTest.this.mContent); System.out.println(B.this.mContent); } } } public static void main(String[] args) { new InnerTest().new B().new C().test(); }}
我们来看看会造成 Handler leak 的代码,如下:
public class MemLeakActivity extends Activity { ... class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { ... } }}所以当我们的内部类 IncomingHandler 发出 Message 后, 根据 Android 异步消息処理机制,Message 会持有 Handler 对象引用,而上面的代码,会持有外部类对象,也就是 MemLeakActivity 对象的引用,导致即使在此 Activity 在调用完 onDestroy( )后,只要 Looper 还没有処理完这个 Message( 比如说这个 Message 是设定为延迟十分钟后再処理),MemLeakActivity 的对象便无法被回收,占用了内存实际上却没有作用,便造成了 Handler Leak 内存泄漏。
解决方法:
使用静态(内部)类 + 弱引用( WeakReference )避免 Activity 被 Message 强引用而无法回收。
public class BaseHandler extends Handler { WeakReference<Callback> mTarget = null; public BaseHandler(Callback cb) { mTarget = new WeakReference<>(cb); } public interface Callback { boolean handleMessage(Message msg); } @Override public void handleMessage(Message msg) { Callback handler = mTarget.get(); if (handler != null) { handler.handleMessage(msg); } }}使用方式
public class HandlerDemoActivity extends Activity implements BaseHandler.Callback, View.OnClickListener{ private BaseHandler mHandler; private final static int MSG_TEST = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_handler_demo); mHandler = new BaseHandler(this); TextView tv = (TextView) findViewById(R.id.tv); tv.setOnClickListener(this); } @Override public boolean handleMessage(Message msg) { final int what = msg.what; if(what == MSG_TEST) { Toast.makeText(this, "TEST", Toast.LENGTH_LONG).show(); } return true; } @Override public void onClick(View v) { mHandler.sendEmptyMessage(MSG_TEST); }}Github 范例
相关参考文章
refs: http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler
0 0
- [Android 内存泄漏] 了解 Handler leak
- Android Handler 内存泄漏
- Android Handler内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android 解决内存泄漏Leak Canary
- 【内存泄漏】Android内存泄漏---Handler
- Java DAO浅析
- jar包置放在WEB-INF/lib下和通过build path导入的区别是什么
- vue中自定义组件(插件)
- 网络数据封装解析(IP,UDP,TCP)
- 关于Java并发编程的总结和思考
- [Android 内存泄漏] 了解 Handler leak
- Throwing cards away I 卡牌游戏 UVA 10935
- VNC秘钥(转)
- java读取config.properties配置文件
- [BZOJ1069][SCOI2007]最大土地面积(凸包+旋转卡壳)
- volley的重试机制及错误处理机制
- 使用高德API接口查询两个地址之间的距离
- 使用greenlet如何实现Python中的并发?
- Mac OS X下Maven的安装与配置