Causes and solutions of Handler memory leaks

1. Reasons for memory leaks caused by Handler

In the Activity, declare the Handler as a non-static inner class or an anonymous inner class, so that the Handle holds a reference to the outer class Activity by default. If the Activity is being destroyed, the Handler still has unfinished or executing Messages, and the Handler holds a reference to the Activity, causing the GC to fail to recycle the Activity, resulting in a memory leak. The following two situations may lead to memory leaks

1. Declare Handler as an anonymous inner class in Activity

   //匿名内部类
   private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };
   new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //大量的操作,activity要销毁时还没结束
        }
    },1000);

2. Declare Handler as a non-static inner class in Activity:

   //非静态内部类
   private class MyHandler extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }

    private MyHandler mHandler = new MyHandler();

Two, the solution

1. Static inner class + weak reference

   private static class MyHandler extends Handler {
        //弱引用,在垃圾回收时,activity可被回收
        private WeakReference<MainActivity> mWeakReference;

        public MyHandler(MainActivity activity) {
            mWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }

2. When the Activity is destroyed, clear the unexecuted or executing Callback and Message in the Handler:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //清空handler管道和队列
        mHandler.removeCallbacksAndMessages(null);
    }

3: Non-static inner class + weak reference, clear the reference when the activity is about to be recycled (troublesome, not recommended)

    private class MyHandler extends Handler {
        //弱引用,在垃圾回收时,activity可被回收
        private WeakReference<MainActivity> mWeakReference;

        public MyHandler() {
            this.mWeakReference = new WeakReference<>(MainActivity.this);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }
    
    private MyHandler mHandler = new MyHandler();

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //手动清除应用
        mHandler.mWeakReference.clear();
    }

Guess you like

Origin blog.csdn.net/xiaowang_lj/article/details/129299746