14.Android 控制Handler内存泄露 技巧
来源:互联网 发布:mac os 软件开发 编辑:程序博客网 时间:2024/05/16 14:20
14.Android 控制Handler内存泄露 技巧
- Android 控制Handler内存泄露 技巧
- Handler 警告
- Handler 内存泄露缘由
- 解决思路
- Handler 通用模板
Handler 警告
In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread’s MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class
这是在用Handler不加static
都会出现的一个警告。
Handler 内存泄露缘由
一个Android应用启动的后,都会创建一个主UI线程,再为这个主UI线程提供一个Looper对象,这样所有的Android框架的事件(Activity的生命周期方法调用和事件)都是放入消息中,再加入Looper处理的MessageQueue中。也就是说主线程的Looper生命周期是与Android应用一样长的。
每次在
Handler.sendMessage(message)
的时候,实际已经发送的message已经包含了改Handler的引用。因为在只有这样Looper才能调用处理改message的handler,进而走到handler.handleMessage(Message msg)
中,不然,你想,我发一个message,Looper怎么知道message处理过后告诉哪个Handler执行handler.handleMessage(Message msg)
。非静态的内部类和匿名的内部类都会隐式地持有了它的对应外部类的引用。静态的内部类不会持有外部类的引用。
出现泄漏的场景:假如我的Handler里做了很多耗时的工作,在Activity.finish()
后Handler还在忙碌的话,就一直持有该Activity的引用,Activity无法回收,进行导致Activity持有的很多资源都无法回收,就会出现Handler的内存泄漏
解决思路
解决思路基本上是:不用非静态的Handler,继承Handler的时候,可以选择
- 独立出一个Handler类
- 静态Handler
以上,这两种方法。因为静态的内部类不会持有外部类(Activity)的引用,所以不会导致外部类实例的内存泄露。
在Android中很多的内存泄露都是由于在Activity中使用了非静态内部类导致的,所以使用时要非静态内部类时要格外注意,如果实例的持有对象的生命周期大于其外部类对象,那么就有可能导致内存泄露。
Handler 通用模板
private TextView handlerTV; private static final int HANDLER_SUCCESS = 206; private static class RefreshHandler extends Handler { private final WeakReference<RefreshUIActivity> mActivity; public RefreshHandler(RefreshUIActivity activity) { mActivity = new WeakReference<>(activity); } /** * Subclasses must implement this to receive messages. * * @param msg */ @Override public void handleMessage(Message msg) { RefreshUIActivity activity = this.mActivity.get(); if (activity != null) { switch (msg.what) { case HANDLER_SUCCESS: { activity.handlerTV.setText("success"); break; } } } } } private final RefreshHandler refreshHandler = new RefreshHandler(RefreshUIActivity.this); private final Runnable mRunnable = new Runnable() { @Override public void run() { Message message = RefreshUIActivity.this.refreshHandler.obtainMessage(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } message.what = HANDLER_SUCCESS; refreshHandler.sendMessageDelayed(message, 2000); } }; private final Thread mThread = new Thread(mRunnable);
- 14.Android 控制Handler内存泄露 技巧
- 14.Android 控制Handler内存泄露 技巧
- android handler 内存泄露
- Android Handler内存泄露
- Android Handler 内存泄露
- android内存泄露:handler
- Android Handler内存泄露分析
- Android内存泄露之Handler
- Android 防内存泄露handler
- Android内存泄露之Handler
- Android开发内存泄露之--Handler引起的内存泄露
- Android 内存泄露 和 Handler内存泄露 整理
- 黑马程序员 android-handler-防止内存泄露
- android 使用handler内存泄露问题
- Android中Handler可能引起内存泄露
- Android App 内存泄露之Handler
- Android -> 如何避免Handler引起内存泄露
- Android App 内存泄露之Handler
- OCP-V13-699
- 一个个熟悉的排序
- jquery validate 及追加html 前端封装JS对象 后台@ReqesutBody 对象即拿到数据
- C#中List的Find方法的使用
- shell浅谈之九子shell与进程处理 http://blog.csdn.net/taiyang1987912/article/details/39529291
- 14.Android 控制Handler内存泄露 技巧
- 如何给textView的drawableTop更换图片
- 解决Laravel5.1使用composer update时出现Call to undefined method getCachedCompilePath()错误
- Sturts2如何获取request参数
- 开源资料下载大全
- 使用Struts2和jQuery EasyUI实现简单CRUD系统(七)——数据分页处理
- 一个PostgreSQL用户眼里的Oracle性能优化
- LVS 配置
- 使用Shell脚本对Linux系统和进程资源进行监控 http://www.csdn.net/article/2012-06-26/2806898