Вопрос по android-asynctask, android – AsyncTask.onCancelled () не вызывается после отмены (true)

8

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   ответа
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
}

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

@Radu В этом весь смысл этого поста, так что вы звонитеonCancelled() вручную, если вы работаете на старых версиях Android. Кроме того, не нацеливайтесь на более старые версии (поэтому вы не можете переопределить его). Ваша цель должна быть последней версией SDK, а минимальный SDK должен быть настолько низким, насколько вы хотите поддерживать.
У меня была такая же проблема, и ваш ответ открыл врата небес :) +1
моя точка зрения - я не могу @ переопределить onCancelled (результат SomeType) и простой onCancelled (). Кроме того, если я нацеливаюсь на старую версию Android, onCancelled () вообще не будет вызываться ...
@Radu Я не знаю, какой код вы используете, или какую задачу вы пытаетесь выполнить. Возможно, вам лучше всего начать новый вопрос, если вы пытаетесь сделать что-то похожее на это и получаете проблемы.
те тоже не называются ....
23

Согласно документу Android API,onCancelled() существует ли начиная с уровня API 3, в то время какonCancelled(Object result) был добавлен только с уровня API 11. Из-за этого, если уровень API платформы ниже 11,onCancelled() будет вызванalways в то время какonCancelled(Object) будет вызванalways иначе.

Итак, если вы хотите запустить свой код на всех уровнях 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 гласит:

Calling the cancel() method will result in onCancelled(Object) being invoked on the UI thread after doInBackground(Object[]) returns. Calling the cancel() method guarantees that onPostExecute(Object) is never invoked.

Это делает мой день.
Хороший ответ, но имя метода существует опечатка. Я думаю, это должно быть "handleOnCancelled".
Вызов метода cancel () гарантирует, что onPostExecute (Object) никогда не будет вызываться, это справедливо только для сот, а в более ранних версиях см. Ответ @eric.

Похожие вопросы