国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android Handler leak分析及解決辦法詳解

2019-10-23 18:34:53
字體:
供稿:網(wǎng)友

Android Handler leak 分析及解決辦法

 In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.

    在Android中,Handler類應(yīng)該是靜態(tài)的,否則,可能發(fā)生泄漏。在應(yīng)用程序線程的MessageQueue中排隊(duì)的Message對(duì)象 還保留他們的目標(biāo)Handler。如果Handler是一個(gè)內(nèi)部類(注:無論是匿名還是非匿名,匿名是比較常見用法),它的外部類將被保留(至于為什么, 請(qǐng)參考Java嵌套類相關(guān)說明)。為了避免泄漏外部類,聲明一個(gè)Handler子類為靜態(tài)內(nèi)部類(注:這樣就避免了Handler對(duì)象對(duì)外部類實(shí)例的自動(dòng)引用),其內(nèi)部持有一個(gè)對(duì)外部類對(duì)象的WeakReference。

    上面是HandlerLeak的詳細(xì)解釋,同時(shí)下劃線部分也提供了解決方案的思路。我們需要再分析一下幾個(gè)泄漏問題:(1) 排隊(duì)中的Message對(duì)象對(duì)Handler的持有導(dǎo)致泄漏;(2)Handler對(duì)象對(duì)外部類(如Activity或Service)實(shí)例的強(qiáng)引用持 有。是由于這兩個(gè)原因同時(shí)作用導(dǎo)致出現(xiàn)泄漏的可能。我們的解決方案可以從原因出發(fā),清除這兩個(gè)原因,就會(huì)比較完整的解決這個(gè)問題。

    方案:(1)針對(duì)第1個(gè)原因,在使用Handler的組件生命周期結(jié)束前清除掉MessageQueue中的發(fā)送給Handler的Message對(duì)象(例如在Activity或Service的onDestroy()中調(diào)用Handler的remove*方法);(2)針對(duì)第2個(gè)原因,Handler的實(shí)現(xiàn)類采用靜態(tài)內(nèi)部類的方式,避免對(duì)外部類的強(qiáng)引用,在其內(nèi)部聲明一個(gè)WeakReference引用到外部類的實(shí)例。

    關(guān)于Handler的remove*方法,這兒介紹一下(可以參考源碼或文檔)

removeCallbacks(Runnable r) ——清除r匹配上的Message。

removeCallbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token為空時(shí),只匹配r。

removeCallbacksAndMessages(Object token) ——清除token匹配上的Message。

removeMessages(int what) ——按what來匹配

removeMessages(int what, Object object) ——按what來匹配

我們更多需要的是清除以該Handler為target的所有Message(包括Callback),那么調(diào)用如下方法即可

    handler.removeCallbacksAndMessages(null);

    最終代碼像下面這樣

package org.dragonboy.example; import java.lang.ref.WeakReference; import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message; /** * @author dragonboyorg@qq.com */public class MyActivity extends Activity {  private MyHandler mHandler;   @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);     mHandler = new MyHandler(this);  }   @Override  protected void onDestroy() {    // Remove all Runnable and Message.    mHandler.removeCallbacksAndMessages(null);     super.onDestroy();  }   static class MyHandler extends Handler {    // WeakReference to the outer class's instance.    private WeakReference<myactivity> mOuter;     public MyHandler(MyActivity activity) {      mOuter = new WeakReference<myactivity>(activity);    }     @Override    public void handleMessage(Message msg) {      MyActivity outer = mOuter.get();      if (outer != null) {        // Do something with outer as your wish.      }    }  }}</myactivity></myactivity>

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 汾西县| 桑植县| 盐池县| 普安县| 金阳县| 修武县| 华亭县| 通化市| 锡林郭勒盟| 松江区| 钟祥市| 什邡市| 张家港市| 汝城县| 沙坪坝区| 西安市| 邮箱| 花莲县| 金平| 临邑县| 宜章县| 柏乡县| 永昌县| 庄河市| 阳西县| 平果县| 关岭| 华亭县| 遂川县| 铅山县| 鄂州市| 广宁县| 库车县| 乌兰浩特市| 曲阜市| 桓仁| 涞水县| 黎平县| 安吉县| 通化县| 仙游县|