我有一个用于内部类的CustomView的类,它们都实现Runnable在一个单独的线程中执行一个Job。
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();
}
}
}
}
如何正确清理它们? 当托管这些CustomViews的Activity被销毁时,它们会自动被销毁吗?
干杯
答案 0 :(得分:1)
不,如果在定时器事件仍处于暂挂状态时销毁活动,则会导致错误。为了避免这种情况,请将WeakReference用于某个对象,递减值。 但是,通常不好的做法 - 混合UI和一些连线,因为它是难以测试的。考虑使用rxJava库,这看起来像
Subscriptioin s = Observable.just(100, TimeUnit.Milliseconds)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.computation())
.subscribe(t -> decrementValue());
你的onPause()方法中的取消了
的作用if (s != null && !s.inUnsubscribed()) {
s.unsubscribe();
s = null;
}
答案 1 :(得分:1)
它不会被破坏导致内存泄漏,因为你的线程将强烈引用你的视图,从而你的活动。
使内部类静态并对run方法中需要的变量保持弱引用。
你可以做的第二件事就是中断你的线程,当你查看从窗口中分离并在线程被中断时检查run方法,但如果你的线程没有做太多工作则不需要。
以下是您的runnable应该是什么样的
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();
}
}
}
我没有检查过任何错误。