溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

在Android應(yīng)用中使用Handler時出現(xiàn) leak如何解決

發(fā)布時間:2020-11-27 15:45:12 來源:億速云 閱讀:226 作者:Leah 欄目:移動開發(fā)

這篇文章給大家介紹在Android應(yīng)用中使用Handler時出現(xiàn) leak如何解決,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

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

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

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

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

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

removeCallbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token為空時,只匹配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>

關(guān)于在Android應(yīng)用中使用Handler時出現(xiàn) leak如何解決就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI