1

我要疯了。我想要一件简单的事情——我有一个很长的任务(从网络上获取几个数据对象)并且我想要取消它的能力。我尝试了很多东西(很多)但没有任何效果

流程是这样的:

  1. 用户点击一个按钮

  2. 我开始工作(我尝试使用AsyncTaskService和)IntentServiceLooper

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

  4. 通知中的意图调用了一个新活动,她的唯一目的是取消正在进行的任务

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

在我看来,最好的选择是使用IntentService(我可以有几个任务排队,IntetService 会按照我想要的顺序执行)但我愿意接受任何类型的实施建议——我不在乎什么代码将是,只是我可以选择取消任务

预先感谢您的帮助

德罗

(我要睡觉了——在同一个问题上花 8 个小时实在太多了)

4

2 回答 2

1

如果您在后台逻辑中无法识别停止条件,那么您使用什么特定操作来停止任务并不重要。干净地完成它的唯一方法是后台工作人员真诚地停止并退出。

可用于取消后台工作的可能方案和解决方案很少。

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

无论如何,如果您的任务不知道被停止的可能性,就没有办法(除了杀死非常糟糕的线程)来停止您的任务。

于 2011-09-08T23:39:32.497 回答
0

好的,我设法做一些接近我想要的事情。

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

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

在 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所以我将能够异步断开连接。

我觉得有点丑但是我没有别的办法

谢谢你们

于 2011-09-09T11:26:51.863 回答