Activity中使用handle存在内存泄漏的隐患
2016-07-22 23:47
411 查看
在Android开发中,经常会在Activity中使用handler来进行线程间通信,使主线程能够实时更新UI。
但是在Android Studio中,发现使用handler时会有黄色的警告提示。提示语为this Handler class should be static or leaks might occur。这条提示的内容就是说:使用handler可能会发生内存泄漏,建议改成静态的。那么为什么Activity中使用handle存在内存泄漏的隐患呢?
因为同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,由于java在生成内部类的时候,原本没有构造器的内部类会被生成一个带外部类参数的构造器,这个内部类就会持有外部类的隐式引用。Handler其实隐式的持有了Activity的引用,只要有消息在队列中,那么handler便无法被回收,如果handler不是static那么使用Handler的Service和Activity就也无法被回收。这就可能导致内存泄露。当然这通常不会发生,除非你发送了一个延时很长的消息。
在java里,非静态内部类和匿名类都会潜在的引用它们所属的外部类。但是,静态内部类却不会。因此将handler改成静态的就可以有效的避免对Activity的隐式引用,从而避免内存泄漏。
另外,如果想要在handler内部去调用所在的外部类Activity,那么可以在handler内部使用弱引用的方式指向所在Activity,这样同样不会导致内存泄漏。
由于内部静态类又不能直接地用activity中的成员变量,在这种情况下,可以使用弱引用。这是因为当Activity被销毁时,系统解除了对该Activity的强引用,gc可以回收掉。但是handle对Activity的强引用如果没有解除,就会造成activity不能被回收,使用若引用就不会造成这种情况。
但是在Android Studio中,发现使用handler时会有黄色的警告提示。提示语为this Handler class should be static or leaks might occur。这条提示的内容就是说:使用handler可能会发生内存泄漏,建议改成静态的。那么为什么Activity中使用handle存在内存泄漏的隐患呢?
因为同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,由于java在生成内部类的时候,原本没有构造器的内部类会被生成一个带外部类参数的构造器,这个内部类就会持有外部类的隐式引用。Handler其实隐式的持有了Activity的引用,只要有消息在队列中,那么handler便无法被回收,如果handler不是static那么使用Handler的Service和Activity就也无法被回收。这就可能导致内存泄露。当然这通常不会发生,除非你发送了一个延时很长的消息。
在java里,非静态内部类和匿名类都会潜在的引用它们所属的外部类。但是,静态内部类却不会。因此将handler改成静态的就可以有效的避免对Activity的隐式引用,从而避免内存泄漏。
另外,如果想要在handler内部去调用所在的外部类Activity,那么可以在handler内部使用弱引用的方式指向所在Activity,这样同样不会导致内存泄漏。
private static class MyHandler extends Handler { WeakReference<MainActivity> mActivity; MyHandler(MainActivity mActivity){ this.mActivity = new WeakReference<MainActivity>(mActivity); } @Override public void handleMessage(Message msg) { //TODO } }
由于内部静态类又不能直接地用activity中的成员变量,在这种情况下,可以使用弱引用。这是因为当Activity被销毁时,系统解除了对该Activity的强引用,gc可以回收掉。但是handle对Activity的强引用如果没有解除,就会造成activity不能被回收,使用若引用就不会造成这种情况。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories