Android内存泄露之Handler


Handler 的生命周期与Activity 不一致导致内存泄露。

如何避免内存泄露:
使用显形的引用,1.静态内部类。 2. 外部类
使用弱引用 2. WeakReference

/**
     * Handler的生命週期與Activity不同
     * 当使用内部类(包括匿名类)来创建Handler的时候,Handler对象会隐式地持有一个外部类
     * 对象(通常是一个Activity)的引用。正常情况下,Activity不再被使用,
     * 它就有可能在GC检查时被回收掉,但由于这时线程尚未执行完,而该线程持有Handler的
     * 引用又持有Activity的引用,就导致该Activity无法被回收(即内存泄露),直到网络请求结束。
     * 另外,如果你执行了Handler的postDelayed()方法,该方法会将你的Handler装入一个Message,
     * 并把这条Message推到MessageQueue中,那么在你设定的delay到达之前,
     * 会有一条MessageQueue -> Message -> Handler -> Activity的链,
     * 导致你的Activity被持有引用而无法被回收。
     */
    private Handler mHandler = new WeakReferenceHandler(this);

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //If null, all callback and messages will be removed.
        mHandler.removeCallbacksAndMessages(null);
    }

外部类WeakReferenceHandler.java

public class WeakReferenceHandler extends Handler{
    private WeakReference<Activity> mActivity;

    public WeakReferenceHandler(Activity activity) {
        mActivity = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (mActivity.get() == null) return;
        launcherPreferenceIntent();
    }

    public void launcherPreferenceIntent() {
        Intent intent = new Intent(mActivity.get(), PreferenceSettings.class);
        mActivity.get().startActivity(intent);
    }
}


WeakReference弱引用,与强引用相对,它的特点是,GC在回收时会忽略掉弱引用,即就算有弱引用指向某对象,但只要该对象没有被强引用指向,该对象就会在被GC检查到时回收掉。对于上面的代码,用户在关闭Activity之后,就算后台线程还没结束,但由于仅有一条来自Handler的弱引用指向Activity,所以GC仍然会在检查的时候把Activity回收掉。这样,内存泄露的问题就不会出现了。



你可能感兴趣的:(Android内存泄露之Handler)