Android Handler导致内存泄漏的解决方案
2016-12-30 11:39
483 查看
最近一段时间,一直在优化项目,遇到了Handler导致的内存泄漏的问题,在解决之余,也发表一下自己的感想,希望对别人有点帮助。
在优化项目的时候,我发现很多人都喜欢用匿名内部类的方式创建一个Handler(当年我也这么写→_→)
比较便捷,但是由于Java的内部类和匿名类会默认持有外部类的引用,如果Handler在等待发送延时消息的时候,Activity被finish,在Message被处理之前,Activity是无法被GC回收的,这就导致了Activity的内存泄漏,而且在Activity被finish之后,绝大多数情况handleMessage已经没有执行的必要了,但是这种方法获取的Handler依然会把这个Message执行下去,做了一些无用的操作而且还容易抛出异常。
网上有用static来修饰Handler来解决匿名类引用外部类的问题,虽然能解决引用外部类的情况,但是却增加了项目初始化的时间成本和方法区的空间,我并不太喜欢这种方式,而是采取了另一种外部类+软引用的方式解决这个问题,代码如下:
CustomHandler
CustomHandleMessage
CustomRunnable
每个想要使用CustomHandler的类都要实现CustomHandleMessage接口,例如:
这样写的好处是,避免了Handler对外部类的引用,不再影响GC对外部类的回收。
打完收工。
PS:本猿也是最近才开始涉及Android内存的优化,有不足或错误的地方还请大家多多指正。
如果有用,顺手点个赞吧 O(∩_∩)O~~
在优化项目的时候,我发现很多人都喜欢用匿名内部类的方式创建一个Handler(当年我也这么写→_→)
private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } };
比较便捷,但是由于Java的内部类和匿名类会默认持有外部类的引用,如果Handler在等待发送延时消息的时候,Activity被finish,在Message被处理之前,Activity是无法被GC回收的,这就导致了Activity的内存泄漏,而且在Activity被finish之后,绝大多数情况handleMessage已经没有执行的必要了,但是这种方法获取的Handler依然会把这个Message执行下去,做了一些无用的操作而且还容易抛出异常。
网上有用static来修饰Handler来解决匿名类引用外部类的问题,虽然能解决引用外部类的情况,但是却增加了项目初始化的时间成本和方法区的空间,我并不太喜欢这种方式,而是采取了另一种外部类+软引用的方式解决这个问题,代码如下:
CustomHandler
/** * Description: TODO * author: Wang * date: 16/12/29 上午10:20 * * Copyright©2016 by wang. All rights reserved. */ public class CustomHandler extends Handler { private SoftReference<CustomHandleMessage> object; public CustomHandler(@NonNull CustomHandleMessage onHandleMessage) { object = new SoftReference(onHandleMessage); } @Override public void handleMessage(Message msg) { CustomHandleMessage onHandleMessage = object.get(); if (onHandleMessage != null) { onHandleMessage.onHandler(msg); } } /** * 发送延时消息 * * @param message * @param delayed */ public void postDelayed(Message message, long delayed) { CustomRunnable runnable = new CustomRunnable(this, message); this.postDelayed(runnable, delayed); } }
CustomHandleMessage
/** * Description: TODO * author: Wang * date: 16/12/29 下午10:10 * * Copyright©2016 by wang. All rights reserved. */ public interface CustomHandleMessage { void onHandler(Message msg); }
CustomRunnable
/** * Description: TODO * author: Wang * date: 16/12/29 下午10:08 * * Copyright©2016 by wang. All rights reserved. */ public class CustomRunnable implements Runnable { private CustomHandler handler; private Message message; public CustomRunnable(CustomHandler handler, Message message) { this.handler = handler; this.message = message; } @Override public void run() { handler.sendMessage(message); } }
每个想要使用CustomHandler的类都要实现CustomHandleMessage接口,例如:
/** * Description: TODO * author: Wang * date: 11/28/16 11:08 AM * * Copyright©2016 by wang. All rights reserved. */ public class TestActivity extends BaseActivity implements CustomHandleMessage { private CustomHandler handler = new CustomHandler(this); @Override public void onHandler(Message msg) { LogUtil.i(TAG, "msg : " + msg.what); } /**省略的方法**/ }
这样写的好处是,避免了Handler对外部类的引用,不再影响GC对外部类的回收。
打完收工。
PS:本猿也是最近才开始涉及Android内存的优化,有不足或错误的地方还请大家多多指正。
如果有用,顺手点个赞吧 O(∩_∩)O~~
相关文章推荐
- android handler消息机制和可能导致内存泄漏的原因
- Android Handler当做内部类,导致内存泄露的问题解决方案
- Android handler导致的内存泄漏
- [置顶] android内存泄漏总结(总结所有导致内存泄露的可能性及解决方案)
- Android Handler内存泄漏详解及其解决方案
- Android锁屏后主Activity的onDestroy方法被调用导致黑屏问题解决方案
- Android实战技巧之三十八:Handler使用中可能引发的内存泄漏
- 关于Android外设键盘导致系统输入法隐藏的解决方案
- Android Weak Handler:可以避免内存泄漏的Handler库
- Android锁屏后主Activity的onDestroy方法被调用导致黑屏问题解决方案
- Android 5.0 权限管理导致的apk安装失败解决方案
- Android开发常见问题之Handler引起的内存泄漏
- Android:Handler,内部类导致的可能内存泄露
- 浅谈Android应用的内存优化及Handler的内存泄漏问题
- Android内存泄漏之 handler
- android 使用Handler 会导致内存泄漏问题
- 您知道吗:未释放事件Handler可能导致内存泄漏
- android应用因为加入js而导致webview一直在加载中的bug解决方案
- android 避免误用context导致内存泄漏
- Android中Handler使用不当导致内存泄露的问题