如何取消Service / IntentService / AsyncTask / Looper

时间:2011-09-08 22:58:15

标签: android service android-asynctask looper intentservice

我在这里疯了。 我想要一个简单的事情 - 我有一个很长的任务(从网上获取几个数据对象),我希望能够取消它。 我尝试了很多东西(很多)并且没有任何作用

流程如下:

  1. 用户点击按钮

  2. 我开始工作(我尝试了AsyncTaskServiceIntentServiceLooper

  3. 该任务负责处理所有事情,包括为进度更新添加持续通知

  4. 通知中的意图呼吁新活动,其唯一目的是取消正在进行的任务

  5. 在cancelActivity中的
  6. 我试图为Service / IntentService调用stopService()或者做 对于Looper Looper.quit()(我不记得我为AsyncTask尝试了什么,不确定是否有取消它的api)

  7. 在我看来,最好的选择是使用IntentService(我可以排好几个任务,IntetService会按照我的意愿顺序完成)但是 我愿意接受任何类型的实现建议 - 我不关心代码是什么,只是我可以选择取消任务

    提前感谢您的帮助

    德罗尔

    (我上床睡觉 - 在同一个问题上花了8个小时太多了)

2 个答案:

答案 0 :(得分:1)

如果您无法识别后台逻辑中的停止条件,则用于停止任务的具体操作无关紧要。干净利落地完成它的唯一方法是背景工作者是否真诚地停止和退出。

您可以使用几种可能的方案和解决方案来取消后台工作。

  • 后台线程执行许多短步骤(例如使用一些循环进行计算)。在这种情况下,请在操作之间检查一些标志(可能是isInterrupted()),如果此标志指示操作必须停止,则退出。
  • 后台线程在监视器上等待。在后台线程上调用interrupt(),在异常处理程序中捕获异常,采取适当的步骤干净地完成此任务并退出。
  • 后台线程正在等待IO。在一般情况下,这个用例很难解决。如果使用某个套接字,可以尝试从外部关闭此套接字并捕获异常。在最坏的情况下,您可以放弃该状态中的线程,如果它从IO返回,它知道它被取消并且必须丢弃IO结果。如果你经常这样做 - 你的内存不足,所以我不会真的推荐它。

在任何情况下,如果它不知道被阻止的可能性,就没有办法(除了杀死非常糟糕的线程)停止你的任务。

答案 1 :(得分:0)

好的,我可以做一些接近我想要的事情。

我正在使用IntentService来排队我的任务。每个新任务都是AsyncTask。 AsyncTask首先发送带有pendingIntent的notificationActivity通知。

单击通知时,用户会收到有关停止任务的警告弹出窗口。如果他在我的IntentService上点击是,那么stopService()

在IntentService中我添加了:

    @Override
public void onDestroy() {
    currentTask.cancel(true);
    if (mNotificationHelper != null)
        mNotificationHelper.completed();
    super.onDestroy();
    stopSelf();
}
我在AsyncTask中添加了

    @Override
protected void onCancelled() {
    isCanclled = true;
    httpClient.getConnectionManager().shutdown();
    mNotificationHelper.completed();
    if (mAsyncTaskListener != null)
        mAsyncTaskListener.AsyncTaskCanceled();
}

这样就会丢弃当前正在运行的所有连接。在执行工作的实际代码中,我需要捕获连接关闭的异常并处理它

所以最后我实际上并没有停止AsyncTask / Service,而是暴露了httpClient所以我将能够以异步方式删除连接。

我觉得有点难看但我别无他法

谢谢大家