取消后不调用AsyncTask.onCancelled()(true)

时间:2012-06-23 00:50:01

标签: android android-asynctask

在2.3.6设备上运行的Android SDK v15。

当我在onPostExecute()电话中呼叫cancel()时,我遇到了doInBackground()仍然被调用的问题。

这是我的代码:

@Override
public String doInBackground(String... params) {
    try {
        return someMethod();
    } catch (Exception e) {
        cancel(true);
    }

    return null;
}

public String someMethod() throws Exception {
    ...
}

我强迫someMethod()抛出异常来测试它,而不是onCancelled被调用,我总是返回onPostExecute()。如果我检查isCancelled()返回的值为true,那么我知道cancel(true)正在执行。

有什么想法吗?

2 个答案:

答案 0 :(得分:23)

根据Android API文档,自API级别3以来onCancelled()已存在,而自{API级别11'以来仅添加了onCancelled(Object result)。因此,如果平台API级别低于11, onCancelled()将被调用始终,而onCancelled(Object)将被调用总是

因此,如果要在所有API级别3及更高级别上运行代码,则需要实现这两种方法。为了获得相同的行为,您可能希望将结果存储在实例变量中,以便可以使用isCancelled(),如下所示:

public class MyTask extends AsyncTask<String, String, Boolean> {
  private Boolean result;
  // . . .
  @Override
  protected void onCancelled() {
    handleOnCancelled(this.result);
  }
  @Override
  protected void onCancelled(Boolean result) {
    handleOnCancelled(result);
  }
  //Both the functions will call this function
  private void handleOnCancelled(Boolean result) {
    // actual code here
  }
}

顺便说一下,Eric的代码不太可行,因为Android API文档说:

  

调用cancel()方法将导致在onCancelled(Object)之后在UI线程上调用doInBackground(Object[])   回报。 调用cancel()方法可以保证   永远不会调用onPostExecute(Object)

答案 1 :(得分:7)

仅从Android API级别11(Honeycomb 3.0.x)开始支持

onCancelled。这意味着,在Android 2.3.6设备上,它不会被调用。

您最好的选择是onPostExecute

protected void onPostExecute(...) {
    if (isCancelled() && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        onCancelled();
    } else {
        // Your normal onPostExecute code
    }
}

如果您想避免版本检查,可以改为:

protected void onPostExecute(...) {
    if (isCancelled()) {
        customCancelMethod();
    } else {
        // Your normal onPostExecute code
    }
}
protected void onCancelled() {
    customCancelMethod();
}
protected void customCancelMethod() {
    // Your cancel code
}

希望有所帮助! :)