我正在尝试实现一个类,它可以管理传入的Runnables并取消任何Runnables,无论它们在代码中的位置都是有保证的。
例如,在Android中,我希望能够执行以下操作。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
manager.submit(new Runnable() {
@Override
public void run() {
someLongRunningTaskThatCallsTheUi();
}
});
}
@Override
public void onPause() {
manager.cancel(); // cancels all Runnables to avoid issues with calling the UI
}
当Future的cancel()
方法实际上不能保证取消Runnable代码并且ExecutorService的shutdownNow()
具有相同的问题时,我如何处理此问题?
从我所看到的情况来看,我需要在我要调用的每一段UI代码之前添加一个Thread.currentThread().isInterrupted()
的检查,然后退出该方法以避免进一步调用。
答案 0 :(得分:0)
考虑使用AsyncTask
。取消AsyncTask
并不保证后台工作将停止,除非任务检查自己的状态。但取消确保不会调用onProgressUpdate
和onPostExecute
。如果onProgressUpdate
不足以在步骤之间更新UI,请将每个步骤放入自己的任务中。
AsyncTask
的一些提示:
他们至少改变了默认线程池几次。如果您想要更好地控制执行,请使用executeOnExecutor
启动任务。
谨防持有对活动的引用。一个不好的建议(由一本备受好评的书IIRC推广)表示要为活动提供WeakReference
并在访问UI之前检查它。这是错误的,因为框架可能在调用onDestroy
后保留对活动的引用,并且当它确实清除其引用时,WeakReference
将不会变为空,直到GC注意到活动不可强烈到达。您应该在活动中维护一组正在运行的任务,并在活动暂停或销毁时取消它们。
要使任务在配置更改中保持运行,请将其托管在保留的无头片段中。