后台线程任务处理完成后,常用Handler来更新ui事件,常用代码如下:
private Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
if (msg.what == 1) {
listAdapter.notifyDataSetChanged();
}
}
};
这段代码可能造成内存泄漏,原因是:Handler作为Activity的内部类创建时,隐式持有了外部类Activity的引用。而Handler一般会伴随一个耗时的后台线程(如网络下载图片),当后台线程执行完毕时,通过handler来更新界面。但如果在网络请求的过程中关闭了Activity,此时线程尚未执行完,而该线程持有handler的引用,handler又持有外部Activity的引用,导致该Activity无法被内存回收,直到网络请求结束。
类似的使用Hanlder.postDelayed方法,Message对象持有当前handler的引用,而Message又存放在MessageQueue中,那么在dalay到达之前,一直会持有外部Activity的引用,导致内存无法回收。
为了避免Handler引起的内存泄漏,可以使用一下几种方法
一、程序保护
1)在Activity关闭前,停止后台线程;
2)在Activity关闭前,删除所有的待处理message。
// If null, all callbacks and messages will be removed.
mHandler.removeCallbacksAndMessages(null);
二、静态内部类
在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。
可以使用弱引用来操作Activity中的对象。
static class StaicHandler extends Handler {
WeakReference<Activity> mWeakReference;
public StaicHandler (Activity activity) {
mWeakReference = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
Activity activity = mWeakReference.get();
if(activity != null) {
if (msg.what == 1) {
activity.***
}
}
}
}