清理实现Runnable的内部类

时间:2016-11-25 20:16:27

标签: java android multithreading performance runnable

我有一个用于内部类的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被销毁时,它们会自动被销毁吗?

干杯

2 个答案:

答案 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();
        }
    }
}

我没有检查过任何错误。