Clean Inner Class 实现 Runnable
Clean Inner Class implementing Runnable
我有一个 Class 用于必须在内部 Classes 的 CustomView,两者都实现 Runnable 以在单独的线程中执行作业。
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();
}
}
}
}
如何正确清理它们?
当托管这些 CustomView 的 Activity 被销毁时,它们会自动被销毁吗?
干杯
不可以,如果 Activity 在定时器事件未决时被销毁会导致错误。为避免这种情况,对某些对象使用 WeakReference,递减值。
但是,通常这是不好的做法 - 混合 UI 和一些 ligic,因为它很难测试。考虑使用 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;
}
它不会被破坏导致内存泄漏,因为您的线程将对您的视图具有强引用,因此您的 activity。
使内部 class 静态化并保持对 运行 方法中所需变量的弱引用。
您可以做的第二件事是中断您的线程,当您查看与 window 分离并检查 运行 方法是否线程被中断时,尽管如果您的线程没有必要线程没有做太多工作。
这是您的 运行nable 的样子
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();
}
}
}
我没有检查任何错误。
我有一个 Class 用于必须在内部 Classes 的 CustomView,两者都实现 Runnable 以在单独的线程中执行作业。
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();
}
}
}
}
如何正确清理它们? 当托管这些 CustomView 的 Activity 被销毁时,它们会自动被销毁吗?
干杯
不可以,如果 Activity 在定时器事件未决时被销毁会导致错误。为避免这种情况,对某些对象使用 WeakReference,递减值。 但是,通常这是不好的做法 - 混合 UI 和一些 ligic,因为它很难测试。考虑使用 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;
}
它不会被破坏导致内存泄漏,因为您的线程将对您的视图具有强引用,因此您的 activity。
使内部 class 静态化并保持对 运行 方法中所需变量的弱引用。
您可以做的第二件事是中断您的线程,当您查看与 window 分离并检查 运行 方法是否线程被中断时,尽管如果您的线程没有必要线程没有做太多工作。
这是您的 运行nable 的样子
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();
}
}
}
我没有检查任何错误。