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

Pol*_*ing 8 android android-asynctask

Android SDK v15在2.3.6设备上运行.

我有一个问题,onPostExecute()当我在通话cancel()doInBackground()呼叫时,仍在呼叫.

这是我的代码:

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

    return null;
}

public String someMethod() throws Exception {
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

有任何想法吗?

小智 23

根据Android的API文档,onCancelled()是因为有API级别为3,而onCancelled(Object result)只是因为正因为如此API级别11已被添加,如果平台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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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


Eri*_*ric 7

onCancelled自Android API级别11(Honeycomb 3.0.x)起仅支持.这意味着,在Android 2.3.6设备上,它不会被调用.

你最好的选择是onPostExecute:

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

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

protected void onPostExecute(...) {
    if (isCancelled()) {
        customCancelMethod();
    } else {
        // Your normal onPostExecute code
    }
}
protected void onCancelled() {
    customCancelMethod();
}
protected void customCancelMethod() {
    // Your cancel code
}
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!:)