2016-11-25 47 views
0

我有一個CustomView類具有內部類,都實現了Runnable在單獨的線程中執行一個任務。清潔內部類實現Runnable

public class ValueSelector extends LinearLayout{ 

..... 

private class AutoIncrementer implements Runnable { 

    @Override 
    public void run() { 
     if (plusButtonIsPressed) { 
      incrementValue(); 
      mHandler.postDelayed(new AutoIncrementer(), REPEAT_INTERVAL_MS); 
     } else { 
      mHandler.removeCallbacks(this); 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

private class AutoDecrementer implements Runnable { 
    @Override 
    public void run() { 
     if (minusButtonIsPressed) { 
      decrementValue(); 
      mHandler.postDelayed(new AutoDecrementer(), REPEAT_INTERVAL_MS); 
     } else { 
      mHandler.removeCallbacks(this); 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 
} 

如何正確清理它們? 當託管這些CustomView的活動被破壞時,它們是否會自動銷燬?

乾杯

+0

他們永遠不會被「摧毀」。在Java變得無法訪問之後,它會在垃圾回收一段時間之後收集垃圾,與Java中的任何其他對象實例一樣。在這種情況下,這可能會在線程停止運行後一段時間。 – Andreas

+0

正常的內部類包括對頂級類的隱式引用,因此當活動被銷燬時仍然會引用該引用,並且gc不會清除此問題,因此需要使內部類爲靜態,並且還使用weakreference並對長時間運行的作業使用線程處理程序,並使用runOnUiThread方法你可以更新你的UI –

回答

1

它不會破壞導致內存泄漏,因爲你的線程會產生強烈參考您的觀點,並因此參考您的活動。

使內部類爲靜態,並在run方法中持有對所需變量的弱引用。

你可以做的第二件事是中斷你的線程,當你查看從窗口脫離並且檢查run方法時,如果線程被中斷或者沒有,儘管沒有必要如果你的線程沒有做太多的工作。

這是你運行的應該是什麼樣子

private static class AutoDecrementer implements Runnable { 

    AutoDecrementer (ValueSelector valueSelector){ 
     this.weakRef = new WeakReference<>(valueSelector); 
    }  


    @Override 
    public void run() { 
     ValueSelector valueSelector = (ValueSelector)weakRef.get(); 
     if(valueSelector == null){ 
      return ; 
      } 

     if (valueSelector.minusButtonIsPressed) { 
      valueSelector .decrementValue(); 
      valueSelector .mHandler.postDelayed(new AutoDecrementer(), REPEAT_INTERVAL_MS); 
     } else { 
      valueSelector.mHandler.removeCallbacks(this); 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

我沒有檢查是否有錯誤。

+0

它在代碼中看起來如何?我已經把內部的類靜態化了,但是幾乎所有的東西都需要變成靜態的。此外,run()方法中使用的布爾值不能是WeakReference等Cheers –

+0

似乎工作正常。謝謝! 你可能會提到的錯誤是什麼? 乾杯 –

+0

意思是不要複製和粘貼,使用這個想法,我很高興它爲你工作 –

1

不,如果活動被破壞,而計時器事件仍懸而未決它會導致錯誤。爲了避免這種情況,使用WeakReference來對某個對象進行遞減值。 但是,通常這是不好的做法 - 混合UI和一些ligic,因爲它是難以測試的。考慮使用rxJava庫,這看起來像

Subscriptioin s = Observable.just(100, TimeUnit.Milliseconds) 
.subscribeOn(Schedulers.io()) 
.observeOn(AndroidSchedulers.computation()) 
.subscribe(t -> decrementValue()); 
在你的onPause()方法

取消actioin通過

if (s != null && !s.inUnsubscribed()) { 
s.unsubscribe(); 
s = null; 
}