【发布时间】:2023-03-05 15:03:01
【问题描述】:
我正在使用在侦听器事件上取消并重新启动的计时器。除了定时器线程泄漏了整个外部类之外,一切都很好。
我的定时器实现如下:
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 Analyzer 来追踪问题并最终解决了问题。我还用回调注释掉了这条线,但线程仍然泄漏,所以它肯定是计时器本身。但是我真的不明白该代码有什么问题。
据我研究,问题在于匿名内部类 (new Timertask()) 持有对外部类的引用,因此可能泄漏整个上下文。但是我仍然不明白为什么在线程用完后(150 ms + 之后)计时器以及对上下文的引用没有被垃圾收集。
这种情况下的上下文是否在线程完成后仍然没有释放?
最后我该如何解决这个泄漏?我将计时器设置为 null,但这并没有解决我的问题。
编辑
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()
【问题讨论】:
-
timer是如何以及在哪里定义的? -
定时器定时器;就在类的标题中。你是这个意思吗?
-
是的,但是在您的问题中发布确切的代码,包括所有修饰符。没有类的标题这样的东西。
-
我只是指在课程开头的标题:)
-
我理解你,但我还是想看看真正的代码 :) 你有没有尝试在一个不是 Activity 的类中这样做?
标签: java android multithreading memory-leaks timer