关于Handler和AsyncTask内存泄漏的解决办法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mo_feng_/article/details/82740460

一、Handler的内存泄漏

This Handler class should be static or leaks might occur (anonymous android.os.Handler) less... (Ctrl+F1) 
Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. 
If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. 
If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, 
as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer 
class and pass this object to your Handler when you instantiate the Handler; Make all references to members 
of the outer class using the WeakReference object.

造成Handler泄漏的原因是,Activity退出时,Handler无法及时退出导致内存泄漏(写得简单了些)
解决办法:
A、静态内部类+弱引用
静态内部类默认不持有外部类的引用,所以改成静态内部类即可。同时,这里采用弱引用来持有Activity的引用。

private static class MyHalder extends Handler {

        private WeakReference<Activity> mWeakReference;

        public MyHalder(Activity activity) {
            mWeakReference = new WeakReference<Activity>(activity);
        }

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

B、Activity退出时,移除所有信息
移除信息后,Handler将会跟Activity生命周期同步

 @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }

二、AsyncTask的内存泄漏

This AsyncTask class should be static or leaks might occur (com.xxx.FadeTimer) less... (Ctrl+F1) 
A static field will leak contexts.  Non-static inner classes have an implicit reference to their outer class. If that outer class is for example a Fragment or Activity, then this reference means that the long-running handler/loader/task will hold a reference to the activity which prevents it from getting garbage collected.  Similarly, direct field references to activities and fragments from these longer running instances can cause leaks.  ViewModel classes should never point to Views or non-application Contexts.

解决办法和Handler类似
A、静态内部类+弱引用

private static class MyTask extends AsyncTask<Void, Void, String> {

        private WeakReference<MyActivity> activityReference;

        // only retain a weak reference to the activity 
        MyTask(MyActivity context) {
            activityReference = new WeakReference<>(context);
        }

        @Override
        protected String doInBackground(Void... params) {
            return "task finished";
        }

        @Override
        protected void onPostExecute(String result) {
            // get a reference to the activity if it is still there
            MyActivity activity = activityReference.get();
            if (activity == null || activity.isFinishing()) return;
            // modify the activity's UI
            TextView textView = activity.findViewById(R.id.textview);
            textView.setText(result);
            // access Activity member variables
            activity.mSomeMemberVariable = 321;
        }
    }

猜你喜欢

转载自blog.csdn.net/mo_feng_/article/details/82740460