AsyncTask.onCancelled () не вызывается после отмены (true)

Android SDK v15 работает на устройстве 2.3.6.

У меня проблема, когда onPostExecute() все еще вызывается, когда я doInBackground() 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) .

Есть идеи?

Согласно документу API Android, onCancelled() существует с уровня API 3, в то время как onCancelled(Object result) был добавлен только с уровня API 11. Из-за этого, если уровень API платформы ниже 11, onCancelled() будет onCancelled(Object) всегда, когда 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 } } 

Кстати, код Эрика вряд ли работает, потому что в документе API 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 } 

Надеюсь, это поможет! 🙂