2015-02-23 244 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); 
    } 
}