2012-06-23 9 views
6

Android SDK v15 ejecutándose en un dispositivo 2.3.6.AsyncTask.onCancelled() no se llama después de cancelar (verdadero)

Tengo un problema donde todavía se llama al onPostExecute() cuando llamo a cancel() dentro de una llamada doInBackground().

Aquí está mi código:

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

    return null; 
} 

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

estoy forzando someMethod() a lanzar una excepción a probar esto, y en vez de ser llamado onCancelled, siempre vuelvo a onPostExecute(). Si marqué isCancelled(), el valor devuelto es verdadero, entonces sé que se está ejecutando cancel(true).

¿Alguna idea?

Respuesta

6

onCancelled solo es compatible desde Android API nivel 11 (Honeycomb 3.0.x). Esto significa que, en un dispositivo Android 2.3.6, no se llamará.

Su mejor opción es tener esto en onPostExecute:

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

Si se quiere evitar la comprobación de versión, en su lugar puede hacer:

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

Espero que ayude! :)

+1

los que no son llamados ya sea .... – Radu

+0

@Radu no tengo idea de un código que está usando o la tarea que estamos tratando de lograr. Probablemente sea mejor que empiece una nueva pregunta si ha estado tratando de hacer algo similar a esto y está recibiendo problemas. – Eric

+0

mi punto es que no puedo @ anular el onCancelled (SomeType resultado) y el simple onCancelled(). Además, si apunto a la versión anterior de Android, no se llamará a onCancelled() en absoluto ... – Radu

21

De acuerdo con el documento de la API de Android, onCancelled() es allí desde el nivel API 3, mientras que onCancelled(Object result) se había añadido sólo a partir de API de nivel 11. Debido a que, si el nivel de API de la plataforma está por debajo de 11, onCancelled() se invocará siempre mientras onCancelled(Object) se invocará siempre de lo contrario.

Por lo tanto, si desea ejecutar su código en todos los niveles de API 3 y superiores, debe implementar ambos métodos. Con el fin de tener el mismo comportamiento es posible que desee almacenar el resultado en una variable de instancia para que isCancelled() se puede utilizar como se muestra a continuación:

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

Por cierto, el código de Eric hace el trabajo no es probable debido a que la documentación del API de Android dice:

al llamar al método cancel() dará lugar a onCancelled(Object) se invoca en el subproceso de interfaz de usuario después de doInBackground(Object[]) devoluciones. Llamar al método cancel() garantiza que onPostExecute(Object) nunca se invoca.

+0

Me alegra el día. –

+1

Buena respuesta, pero el nombre del método existe un error tipográfico. Supongo que debería ser "handleOnCancelled". – TonyQ

+1

Llamar al método cancel() garantiza que onPostExecute (Object) nunca se invoca, eso es solo correcto para honeycomb y más tarde para versiones anteriores referirse a @eric answer –

Cuestiones relacionadas