AsyncTask.onCancelled() не вызывается после отмены (true)
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 {
...
}
Я заставляю someMethod()
бросить исключение, чтобы проверить это, и вместо вызова onCancelled я всегда возвращаюсь к onPostExecute()
, Если я проверю isCancelled()
возвращаемое значение истинно, поэтому я знаю, что cancel(true)
выполняется
Есть идеи?
2 ответа
Согласно документу 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
}
}
Кстати, код Эрика, скорее всего, не работает, потому что док Android API говорит:
Вызов
cancel()
метод приведет кonCancelled(Object)
вызывается в потоке пользовательского интерфейса послеdoInBackground(Object[])
возвращается. Вызов метода cancel() гарантирует, чтоonPostExecute(Object)
никогда не вызывается.
onCancelled
поддерживается только с уровня API Android 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
}
Надеюсь, это поможет!:)