非静态内部类和匿名内部类造成内存泄漏也是一个很常见的情景,经常会遇到的 Handler 问题就是这样一种情况,如果我们在field声明一个 Handler 变量:
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
由于在 Java 中,非静态内部类(包括匿名内部类,比如这个 Handler 匿名内部类)会引用外部类对象(比如 Activity),而静态的内部类则不会引用外部类对象。所以这里 Handler 会引用 Activity 对象,当它使用了 postDelayed 的时候,如果 Activity 已经 finish 了,而这个 handler 仍然引用着这个 Activity 就会致使内存泄漏,因为这个 handler 会在一段时间内继续被 main Looper 持有,导致引用仍然存在,在这段时间内,如果内存吃紧至超出,就很危险了。
解决办法就是大家都知道的使用静态内部类加 WeakReference:
public static class StaticHandler extends Handler {
private final WeakReference<Activity> mActivity;
public StaticHandler(Activity activity) {
mActivity = new WeakReference<Activity>(activity);
}
@Override public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
使用的时候使用此类或者此类的继承类 private StaticHandler mHandler = new StaticHandler(this);