一般情况下,我们说到 Handler 内存泄漏,指的是 Handler 泄漏掉了所在的 Activity。
class MyActivity extends Activity{
public Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
上面的代码就有可能导致内存泄漏。代码中的 Handler 使用了 MyActivity 内部类的写法,在 Java 中,非静态内部类和匿名内部类都会隐式的持有一个外部类的引用。所以,这个 Handler 就持有了 Activity 的引用。
由于 Handler 的特性问题,接下来有可能遇到几个问题。
-
用户关掉了 Activity,但是还有延迟消息没有发出或者发出去的消息还没被执行,由于 MessageQueue 持有这个 Message 的引用,Message 持有 Handler 的引用, Handler 又持有 Activity 的引用,这就导致这个已经关闭的 Activity 迟迟不能被内存回收;
-
Handler 发出的消息在执行耗时任务,无法回收;
问题有了,只需要给出对应的解决办法就好了。
-
Handler 经常被用来发延时消息,我们需要保证 Activity 被 finish() 的时候,该线程的消息队列中没有这个 Handler 发出的消息。一个补救的办法就是在该类需要回收的时候,手动地把消息队列中的消息清空:
mHandler.removeCallbacksAndMessages(null);
-
不让 Handler 持有 Activity 的实例,可以让该Handler成为静态内部类,因为静态内部类是不持有外部类的实例的;同时弱引用外部 Activity。
public class MyActivity extends Activity { private static class MyHandler extends Handler { private final WeakReference<ShanActivity> mActivity; public MyHandler(Activity activity) { mActivity = new WeakReference<Activity>(activity); } @Override public void handleMessage(Message msg) { Activity activity = mActivity.get(); if (activity != null) {} } } private MyHandler mHandler = new MyHandler(); @Override protected void onDestroy() { mHandler.removeCallbacksAndMessages(null); } }
-
将 Handler 放到抽取出来放入一个单独的顶层类文件中,弱引用目标 Activity。
public class WeakRefHandler extends Handler { private WeakReference<Callback> mWeakReference; public WeakRefHandler(Callback callback) { mWeakReference = new WeakReference<Handler.Callback>(callback); } public WeakRefHandler(Callback callback, Looper looper) { super(looper); mWeakReference = new WeakReference<Handler.Callback>(callback); } @Override public void handleMessage(Message msg) { if (mWeakReference != null && mWeakReference.get() != null) { Callback callback = mWeakReference.get(); callback.handleMessage(msg); } } }
网友评论