关于AndroidAnnotations取消后台任务的方法
AndroidAnnotations是一个优秀的开源依赖注入框架,可以通过添加依赖大大减少代码量,达到代码易读易维护的目的。
AndroidAnnotations中,是通过@Background将方法放入后台线程中的,并且可以设置该后台任务的 id 属性,然后就可以调用 BackgroundExecutor.cancelAll()来取消该任务。
在实际开发中遇到的问题是,如果一个后台任务已经开始,则上述取消命令并不能使之立即结束。
在AsyncTask中取消任务的方法是调用cancel(boolean),并且要在doInBackground(Object[])中及时调用isCancelled()判断是否收到取消请求,以中断后续操作。
于是我想,AndroidAnnotations应该是采取类似的方式,需要在后台任务的代码中手动判断是否收到取消的请求。这就引出了问题的关键:这个请求如何获取?
经过查找资料,BackgroundExecutor.cancelAll(String id, boolean mayInterruptIfRunning)方法中如果设置
mayInterruptIfRunning
为 true,并且目标任务已经开始执行,
那么就会发出一个 打断(
interrupt) 该任务的请求。事实上类似于(就是?)Thread.interrupt()方法。(关于该方法的详细解释,可以看这里 )。基本原理是,该方法会在目标线程中置入一个打断标记,然后由该线程来(选择是否)接收和处理这个标记。而这个接收方法,就是Thread.interrupted()。
所以,在使用AndroidAnnotations一个可行的取消后台任务的方法,是先调用BackgroundExecutor.cancelAll(“id“, true),然后在后台任务的代码中用Thread.interrupted()判断是否收到打断请求,决定是否进行后续操作。
补充:有一些方法(如Object.wait()/Thread.sleep())会消耗掉线程的打断标记,从而使得后续的Thread.interrupted()
返回false,即没有接收到打断请求。所以,不要在你想要处理打断请求之前调用这些方法。
如果大家对该问题有更好的方法,欢迎留言交流。