2012-06-23 12 views
6

Android SDK v15 działa na urządzeniu 2.3.6.Funkcja AsyncTask.onCancelled() nie jest wywoływana po anulowaniu (true)

Mam problem, w którym onPostExecute() jest nadal wywoływana, gdy dzwonię pod numer cancel() w ramach połączenia doInBackground().

Oto mój kod:

@Override 
public String doInBackground(String... params) { 
    try { 
     return someMethod(); 
    } catch (Exception e) { 
     cancel(true); 
    } 

    return null; 
} 

public String someMethod() throws Exception { 
    ... 
} 

jestem zmuszając someMethod() rzucić wyjątek przetestować to na zewnątrz i zamiast onCancelled miano, zawsze wrócić do onPostExecute(). Jeśli sprawdzę isCancelled() zwrócona wartość jest prawdziwa, więc wiem, że jest wykonywana cancel(true).

Wszelkie pomysły?

Odpowiedz

6

onCancelled jest obsługiwany tylko od wersji Android API poziomu 11 (Honeycomb 3.0.x). Oznacza to, że na urządzeniu z systemem Android 2.3.6 nie będzie on wywoływany.

Najprościej jest mieć to na onPostExecute:

protected void onPostExecute(...) { 
    if (isCancelled() && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
     onCancelled(); 
    } else { 
     // Your normal onPostExecute code 
    } 
} 

Jeśli chcesz uniknąć sprawdzanie wersji, można zamiast tego zrobić:

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

nadzieję, że pomoże! :)

+1

te nie są nazywane albo .... – Radu

+0

@Radu nie mam pojęcia kodu używasz lub zadanie starasz się osiągnąć. Prawdopodobnie najlepiej byłoby rozpocząć nowe pytanie, jeśli próbujesz zrobić coś podobnego i otrzymujesz problemy. – Eric

+0

moim celem jest nie mogę @ zastąpić onCancelled (wynik SomeType) i prosty onCancelled(). Ponadto, jeśli celuję w starą wersję Androida, funkcja onCancelled() nie będzie w ogóle wywoływana ... – Radu

21

Według dokumentu Android API, onCancelled() jest tam od poziomu API 3, natomiast onCancelled(Object result) została dodana dopiero od poziomu API 11. Ze względu na to, czy poziom platformy API jest poniżej 11, onCancelled() zostanie wywołany zawsze podczas gdy onCancelled(Object) będzie wywoływane zawsze w przeciwnym razie.

Tak więc, jeśli chcesz uruchomić swój kod na wszystkich poziomach API 3 i wyższych, musisz zaimplementować obie metody. Aby mieć takie samo zachowanie może chcesz zapisać wynik w zmiennej instancji, tak aby isCancelled() mogą być stosowane, jak pokazano poniżej:

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

Nawiasem mówiąc, kod Erica nie prawdopodobny pracy, ponieważ Android API doc mówi:

wywołanie metody cancel() spowoduje onCancelled(Object) powołano się na wątku UI po doInBackground(Object[]) zwrotów. Wywołanie metody cancel() gwarantuje, że onPostExecute(Object) nie zostanie wywołane.

+0

To sprawia, że ​​mój dzień. –

+1

Dobra odpowiedź, ale nazwa metody istnieje literówka. Myślę, że powinno to być "handleOnCancelled". – TonyQ

+1

Wywołanie metody cancel() gwarantuje, że onPostExecute (Object) nigdy nie zostanie wywołany, to tylko w przypadku honeycomb, a później w przypadku wcześniejszych wersji, odwołuj się do @eric answer –

Powiązane problemy