代碼分析:Android中常見Handler內(nèi)存泄漏

Handler內(nèi)存泄漏原因

Handler是我們常用的一個(gè)對(duì)象,在之前的文章已經(jīng)分析了Handler的工作機(jī)制,然而,在使用Handler的過程中容易造成內(nèi)存泄漏。常見的場景如下。
場景一

public class MainActivity extends AppCompatActivity {
    private CalendarPageView calendar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                
            }
        },10000);
    }
}

在Java中在內(nèi)部創(chuàng)建對(duì)象之后會(huì)隱式的持有外部對(duì)象,也就是說new Handler()之后Handler對(duì)象對(duì)Activity就有了一個(gè)持有,那么此時(shí)finish掉Activity的話是沒辦法回收的。這就造成了內(nèi)存泄漏。
場景二

    private Handler handler = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            Activity activity = MainActivity.this;
        }
    };

在里面Handler不僅僅是隱式的持有,也有顯示的持有Activity,若執(zhí)行延時(shí)操作也會(huì)導(dǎo)致Activity無法被回收。
對(duì)于隱式持有,Handler的postDelayed方法,實(shí)際上是先把Message添加到MessageQueue中,進(jìn)而等待Message的執(zhí)行,所以而Message又是在主線程的Looper中穿件,所以持有鏈接是ActivityThread->Looper->MessageQueue->Message->Handler->Activity
Handler內(nèi)存泄漏解決方案
首先Handler的具體實(shí)現(xiàn)使用靜態(tài)內(nèi)部類的方式。再對(duì)外部的Activity進(jìn)行弱引用。

    static class MyHanler extends Handler{
        WeakReference<Activity> activity;

        public MyHanler(Activity activity) {
            this.activity = new WeakReference<Activity>(activity);
        }

        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            Activity act = activity.get();
            if(null == act){
                return;
            }
        }
    }

然后再創(chuàng)建Handler,由于Activity是弱引用,這樣當(dāng)Activity結(jié)束之后Handler無法繼續(xù)持有Activity,這樣避免內(nèi)存泄漏。
當(dāng)然若是Handler有延時(shí)操作,那么Handler依然會(huì)存在,如果延時(shí)消息在Activity銷毀之后沒有存在的必要,那么我們可以在Activity銷毀之后刪除Handler的消息。

    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容