2015-02-23 245 views
3

我正在使用取消並重新啓動偵聽程序事件的定時器。除了定時器線程泄漏整個外部類以外,它一切正常。定時器發生內存泄漏

我定時器實現如下:

 if(timer != null) { 
      timer.cancel(); 
      timer = null; 
      timer = new Timer(); 
     } 
     timer.schedule(new TimerTask() { // Thread leaks!!!! 
      @Override 
      public void run() { 
       mCallback.onHeaderMoving(newToolbarTranslationY); 
      } 
     } , 150); 

我用MAT分析儀來追蹤問題,結束了那裏。我也用回調註釋掉了這一行,但是這個線程仍然會泄漏,所以它就是定時器本身。不過,我並不真正瞭解該代碼的問題。

據我所知,我的研究問題是匿名內部類(新的Timertask())持有對外部類的引用,因此可能泄漏整個上下文。但我仍然不明白爲什麼定時器以及對上下文的引用在線程用完之後(150 ms +之後)沒有被垃圾回收。

即使在線程完成後,這種情況下的上下文是否仍然未被釋放?

最後,我該如何解決這個泄漏?我將計時器設置爲空,但這並沒有解決我的問題。

編輯

private OnHeaderMovingCallBack mCallback; 
private Timer timer = new Timer(); 

//... some other parameters 


public ScrollingToolbarManager(View toolbar , View pagerStrip , AbsListView listView , OnHeaderMovingCallBack headerMovingCallBack){ 
    this.toolbar = toolbar; 
    this.pagerStrip = pagerStrip; 

    this.listView = listView; 

    mCallback = headerMovingCallBack; 

    changeStartValues(); 

} 

public static interface OnHeaderMovingCallBack{ 
    public void onHeaderMoving(int translationY); 
} 

public void moveHeader(){ 

     //... some calculations 

    //timer implementation from above 
} 

moveHeader()調用列表視圖

+0

'timer'是如何定義的? – m0skit0 2015-02-23 18:32:01

+0

定時器定時器;就在班級的頭上。這是你的意思嗎? – marcel12345689 2015-02-23 18:36:29

+0

是的,但是發佈問題中的確切代碼,包括所有修飾符。沒有類*的標題*。 – m0skit0 2015-02-23 18:39:18

回答

3

的滾動事件如果你覺得現在的問題是,匿名內部類持有外類的引用,那麼只需使用一個名爲靜態內部類 - 這將不會引用。把這樣的東西放在你的班級裏:

static class MyTimerTask extends TimerTask { 
    private OnHeaderMovingCallBack mCallback; 
    int newToolbarTranslationY; 

    public MyTimerTask(OnHeaderMovingCallBack mCallback, int newToolbarTranslationY) { 
     this.mCallback = mCallback; 
     this.newToolbarTranslationY = newToolbarTranslationY; 
    } 

    @Override 
    public void run() { 
     mCallback.onHeaderMoving(newToolbarTranslationY); 
    } 
}