WeakReference 在android中的应用
2015-07-17 11:13
405 查看
首先我们来看一段代码
上面这段低吗没有什么问题,但是在handler对象创建的时候却会报警告:This Handler class should be static or leaks might occur意思是:Handler
类应该为static类型,否则可能会造成内存泄漏。为什么会造成这种情况呢?这种情况就是由于android的特殊机制造成的:当一个android主线程被创
建的时候,同时会有一个Looper对象被创建,而这个Looper对象会实现一个MessageQueue(消息队列),当我们创建一个handler对象时,而handler的
作用就是放入和取出消息从这个消息队列中,每当我们通过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。因此当
Activity被结束后,这个msg在被取出来之前,这msg会继续存活,但是这个msg持有handler的引用,而handler在Activity中创建,会持有Activity的引用,
因而当Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。
这个根本原因就是:Activity在被结束之后,MessageQueue并不会随之被结束,如果这个消息队列中存在msg,则导致持有handler的引用,但是又
由于Activity被结束了,msg无法被处理,从而导致永久持有handler对象,handler永久持有Activity对象,于是发生内存泄漏。但是为什么为static类型就
会解决这个问题呢?因为在java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持
有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。(至于为什么强引用不能够被gc自动回收,而
弱引用对象为什么会被gc回收,可以自行去google)。
所以解决这个警告就有几种方法:
一:将hanlder对象声明为静态的对象。
二:使用静态内部类,通过WeakReference实现对Activity的弱引用。具体实现看以下代码:
三:定义外部类,继承Handler。
public class AutoActivity extends Activity { Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_auto); } }
上面这段低吗没有什么问题,但是在handler对象创建的时候却会报警告:This Handler class should be static or leaks might occur意思是:Handler
类应该为static类型,否则可能会造成内存泄漏。为什么会造成这种情况呢?这种情况就是由于android的特殊机制造成的:当一个android主线程被创
建的时候,同时会有一个Looper对象被创建,而这个Looper对象会实现一个MessageQueue(消息队列),当我们创建一个handler对象时,而handler的
作用就是放入和取出消息从这个消息队列中,每当我们通过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。因此当
Activity被结束后,这个msg在被取出来之前,这msg会继续存活,但是这个msg持有handler的引用,而handler在Activity中创建,会持有Activity的引用,
因而当Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。
这个根本原因就是:Activity在被结束之后,MessageQueue并不会随之被结束,如果这个消息队列中存在msg,则导致持有handler的引用,但是又
由于Activity被结束了,msg无法被处理,从而导致永久持有handler对象,handler永久持有Activity对象,于是发生内存泄漏。但是为什么为static类型就
会解决这个问题呢?因为在java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持
有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。(至于为什么强引用不能够被gc自动回收,而
弱引用对象为什么会被gc回收,可以自行去google)。
所以解决这个警告就有几种方法:
一:将hanlder对象声明为静态的对象。
二:使用静态内部类,通过WeakReference实现对Activity的弱引用。具体实现看以下代码:
public class AutoActivity extends Activity { MyHandler handler = new MyHandler(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_auto); } static class MyHandler extends Handler{ WeakReference<AutoActivity> mactivity; public MyHandler(AutoActivity activity){ mactivity = new WeakReference<AutoActivity>(activity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 100: //在这里面处理msg //通过mactivity.get()获取Activity的引用(即上下文context) break; default: break; } } } }
三:定义外部类,继承Handler。
相关文章推荐
- Android动画之正弦曲线运动
- Android中Listview(四)--分组listview
- 智能储物柜/快递柜系统解析<二>
- Android笔记:inflate的三个参数及其用法
- 图片显示
- Android 使用ViewPager实现左右循环滑动图片
- 【转】Android安全研究经验谈
- Android binder学习一:主要概念
- Android项目无法和服务器建立连接
- Android之断点续传(一)
- Android binder学习一:主要概念
- Android使用Java Web服务器作为中转实现即时通信
- 如何在Android模拟器上安装apk文件[转]
- Android之-----Frame帧动画(Animation)
- 对android.jar进行反编译获得其资源文件
- Android入门常见问题
- 详解Android动画之Frame Animation(转)
- Android之-----GridView使用的方法总结
- Android项目加载后图标不显示解决方案
- 获取Android媒体库中的音乐文件