8

在 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()返回值是否为真,那么我知道它cancel(true)正在执行。

有任何想法吗?

4

2 回答 2

24

根据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
  }
}

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

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

于 2012-12-13T01:03:24.177 回答
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
    }
}

如果你想避免版本检查,你可以这样做:

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

希望有帮助!:)

于 2012-06-23T01:17:07.160 回答