Android - 强力取消AsyncTask

Par*_*ani 62 android android-asynctask

我在我的一个活动中实现了AsyncTask:

 performBackgroundTask asyncTask = new performBackgroundTask();
 asyncTask.execute();
Run Code Online (Sandbox Code Playgroud)

现在,我需要实现"取消"按钮功能,所以我必须停止执行正在运行的任务.我不知道如何停止运行任务(后台任务).

所以请建议我,如何有力地取消AsyncTask?

更新:

我找到Cancel()了相同的方法,但我发现调用cancel(boolean mayInterruptIfRunning)不一定会停止执行后台进程.似乎发生的一切是AsyncTask将执行onCancelled(),并且在完成时不会运行onPostExecute().

Jac*_*alk 90

isCancelled()偶尔检查一下:

 protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled()) break;
    }
    return null;
 }
Run Code Online (Sandbox Code Playgroud)

  • @ user456046是的,你已经在我的代码中指出了我想要添加的确切内容.实际上,我已经实现了cancel()方法,但不知道我们需要在doInBackground()方法中写入这种指示.非常感谢 (2认同)
  • @PareshMayani isCancelled()总是返回false,即使我调用asynctask.cancel(true); (2认同)

Com*_*are 49

打电话cancel()AsyncTask.这是否会实际取消任何东西取决于你正在做什么.引用罗曼盖伊:

如果调用cancel(true),则会向后台线程发送一个中断,这可能有助于中断任务.否则,您应该确保在doInBackground()方法中定期检查isCancelled().您可以在code.google.com/p/shelves上查看此示例.


Yah*_*hel 16

这实际上取决于你在asynctask中做了什么.

如果它是一个处理大量文件的循环,你可以在每个文件之后检查isCanceled()标志是否被引发,然后如果是,则从你的循环中断.

如果它是执行非常长操作的一行命令,那么你无能为力.

最好的解决方法是不使用asynctask的cancel方法并使用你自己的cancelFlag布尔值.然后,您可以在postExecute中测试此cancelFlag,以决定如何处理结果.


Eli*_*345 5

在评论案例中提到的isCancelled() always returns false even i call asynctask.cancel(true);如果我关闭我的应用程序尤其有害,但AsyncTask继续工作.

为了解决这个问题,我通过Jacob Nordfalk以下方式修改了代码提议:

protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled() || (FlagCancelled == true)) break;
    }
    return null;
 }
Run Code Online (Sandbox Code Playgroud)

并在主要活动中添加了以下内容:

@Override
protected void onStop() {
    FlagCancelled = true;
    super.onStop();
}
Run Code Online (Sandbox Code Playgroud)

由于我的AsyncTask是其中一个视图的私有类,因此需要该标志的getter或setter来通知AsyncTask当前实际的标志值.

我多次测试(AVD的Android 4.2.2,空气污染指数17)表明,如果一个的AsyncTask已经执行它doInBackground,然后isCancelled()在没有办法反应(即仍然是假的),以任何企图在取消它,例如mViewGroup.removeAllViews();或期间OnDestroyMainActivity,每一个都会导致意见分离

   @Override 
   protected  void  onDetachedFromWindow() { 
    mAsyncTask.cancel(false); // and the same result with mAsyncTask.cancel(true);
    super.onDetachedFromWindow(); 
   } 
Run Code Online (Sandbox Code Playgroud)

如果我管理强制停止doInBackground()多亏了介绍FlagCancelled,然后onPostExecute()是所谓的,但既不onCancelled()也没有onCancelled(Void result)(因为API级别11)不被调用.(我不知道为什么,因为它们应该被调用,onPostExecute()不应该,"Android API doc说:调用cancel()方法保证永远不会调用onPostExecute(Object)." - IdleSun,回答类似的问题).

另一方面,如果相同的AsyncTask doInBackground()在取消之前没有启动它,那么一切正常,isCancelled()更改为true,我可以检查

@Override
    protected void onCancelled() {
        Log.d(TAG, String.format("mAsyncTask - onCancelled: isCancelled = %b, FlagCancelled = %b", this.isCancelled(), FlagCancelled ));
    super.onCancelled();
}
Run Code Online (Sandbox Code Playgroud)