1. 程式人生 > >關於Handler和AsyncTask記憶體洩漏的解決辦法

關於Handler和AsyncTask記憶體洩漏的解決辦法

一、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;
        }
    }