2017-08-11 68 views
0

this文章中,我修改了活動類中我的處理程序如下:呼叫後

private static class ActivityHandler extends Handler 
{ 
    private final WeakReference<MyActivity> mActivity; 

    public ActivityHandler(MyActivity activity) 
    { 
     mActivity = new WeakReference<MyActivity>(activity); 
    } 

    public final MyActivity getActivity() 
    { 
     return mActivity.get(); 
    } 
} 

處理程序被初始化:

ActivityHandler handler = new ActivityHandler(this); 

然而,在幾個點我的活動邏輯我必須在這個處理程序上調用post。因此,而不是這樣的:

handler.post(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       setSomeProperties(); 
      } 
     }); 

我現在這樣做:

handler.post(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       MyActivity activity = handler.getActivity(); 
       if (activity != null) 
       { 
        activity.setSomeProperties(); 
       } 
      } 
     }); 

不管這種變化的,當我運行應用程序,並檢查HPROF文件泄露活動,我仍然得到指了指handler.post(new Runnable())一行。我究竟做錯了什麼?

p.s.我已經看到很多例子在處理程序上重寫handleMessage,但是,我還沒有能夠與我的案例建立連接並使用它。

回答

1

你正在創建Runnable這是一個匿名類在Activity和匿名類抱到勢必Activity的隱式引用。

亞歷克斯·洛克伍德曾談及這也是在同一篇文章:

要解決出現的內存泄漏時,我們實例匿名 運行的類,我們把這些變量的類 的靜態字段(因爲匿名類的靜態實例並不持有的隱式 參考其外部類)

爲了解決這個問題(來自同一文章):

/** 
    * Instances of anonymous classes do not hold an implicit 
    * reference to their outer class when they are "static". 
    */ 
    private static final Runnable sRunnable = new Runnable() { 
     @Override 
     public void run() { /* ... */ } 
    }; 

但是,我會說,如果Runnable不會超過Activity的生命週期(即,將被銷燬,如果活動被破壞),則不需要將其更改爲靜態字段。

從同一篇文章:

避免使用一個活動的非靜態內部類如果 內部類實例可以活得比活動的生命週期。

從文章的註釋部分另一種解決方案:

不是使Runnable的靜態,你也可以只持有 (非靜態)引用它,並調用 mHandler.removeCallbacks (mRunnable)inDestroy()。

+0

非常感謝您的支持。因此,在sRunnable的run方法中,我將如何調用setSomeProperties(),它是非靜態的? –

+0

與'Handler'類似,您可以創建自己的'Runnable'類繼承'Runnable',並在'WeakReference'中包含'Activity'實例。現在你可以用'Activity'實例調用'setSomeProperties()'。或者在本文的註釋部分中提出的另一種解決方案是在Activity的'onDestroy()'中調用'mHandler.removeCallbacks(mRunnable)',而不是使'Runnable'靜態。你也可以這樣做。 – Bob

+0

再次感謝,這是最有幫助的。 –