在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)
正在执行。
有什么想法吗?
答案 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)
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
}
希望有所帮助! :)