从集合中取消AsyncTasks

时间:2013-01-17 19:31:43

标签: android android-asynctask

假设我有TasksManager,它有静态List任务(不确定列表是好的解决方案),还有静态方法addTaskToList(MyTask task){tasks.add(task);}, removeTaskFromList(MyTask task){tasks.remove(task);} doInBackground()中的每个任务都调用第一个方法,而在onPostExecute()中,第二个方法调用“this”。 MyTask有String字段“method”。

我想取消这个列表的任务,其中task.getMethod()。包含(“url”).. 不确定这段代码是否足够稳定工作..看起来像onCancelled()的任务并不总是被调用,多线程对于我认为的这种方法可能是危险的。

   for (MyTask task : tasks) {
        if (task.getMethod().contains("url")) {
            task.cancel(true);
            break;
        }
    }

以这种方式存储任务是正常的做法,还是可以建议我更优雅?

1 个答案:

答案 0 :(得分:0)

取消AsyncTask并不总是直接/显而易见的事情。如果您使用的是cancel,则还需要确保doInBackground了解isCancelled并且您必须停止自己正在做的事情(请参阅isCancelled的文档) 。

我不建议存储AsyncTask个对象的列表并迭代它们以进行顺序后台工作。这听起来很快就会变得非常混乱。每个AsyncTask都会创建一个新的Thread,这听起来并不像您想要的那样。相反,你可能只想要一个后台线程,你可以做什么?

对于一个后台线程,您可以使用HandlerThread和您自己的Looper,如下所示:

HandlerThread backThread = new HandlerThread("BackLooper", Thread.NORM_PRIORITY);
backThread.start();
Looper backLooper = backThread.getLooper();

private synchronized void runOnBackThread(Runnable r) {
   new Handler(backLooper).post(r);
}

然后,您希望按顺序运行的每个项目都可以通过提交Runnable在后​​台主题上发布。而且,您也可以使用其他Handler帖子变体,postDelayed,postAt等。

而且,根据您正在做的事情,您可能会发现IntentService 非常非常有帮助。 IntentService专门用于“工作队列”类型模式。它有一个后台线程,当你调用它时,你会告诉它一次做一个,并在不需要它时自行消失。

最后,如果您正在为Android寻找一个非常好的通用“任务”类型库,请查看Square的Tape。这与你的问题没有直接关系,但我发现Tape非常方便,可以提供更强大的“排队”任务类型情况。