Estoy convirtiendo mi código de usar Handler
a AsyncTask
. Lo último es excelente en lo que hace: actualizaciones asíncronas y manejo de resultados en el hilo principal de la interfaz de usuario. Lo que no está claro para mí es cómo manejar las excepciones si algo se vuelve loco AsyncTask#doInBackground
.
La forma en que lo hago es tener un controlador de errores y enviarle mensajes. Funciona bien, pero ¿es el enfoque "correcto" o hay una mejor alternativa?
También entiendo que si defino el controlador de errores como un campo de actividad, debería ejecutarse en el hilo de la interfaz de usuario. Sin embargo, a veces (de manera muy impredecible) recibo una excepción que dice que el código activado Handler#handleMessage
se ejecuta en el hilo incorrecto. ¿Debería inicializar el controlador de errores en su Activity#onCreate
lugar? Colocar runOnUiThread
en Handler#handleMessage
parece redundante pero se ejecuta de manera muy confiable.
Respuestas:
Me aferro a
Throwable
oException
en laAsyncTask
instancia misma y luego hago algo con ellaonPostExecute()
, por lo que mi manejo de errores tiene la opción de mostrar un diálogo en pantalla.fuente
AsyncTask
siguiente patrón que describo.Cree un objeto AsyncResult (que también puede usar en otros proyectos)
Devuelva este objeto de sus métodos AsyncTask doInBackground y verifíquelo en postExecute. (Puede usar esta clase como una clase base para sus otras tareas asíncronas)
A continuación se muestra una maqueta de una tarea que obtiene una respuesta JSON del servidor web.
fuente
super()
enAsyncTaskResult
cuando la clase no se extiende algo?Cuando siento la necesidad de manejar Excepciones
AsyncTask
correctamente, lo uso como superclase:Como es normal, anula
doInBackground
en su subclase para hacer el trabajo de fondo, felizmente lanzando excepciones donde sea necesario. Luego se ve obligado a implementaronPostExecute
(porque es abstracto) y esto le recuerda suavemente que maneje todos los tipos deException
, que se pasan como parámetro. En la mayoría de los casos, las excepciones conducen a algún tipo de salida de interfaz de usuario, por lo queonPostExecute
es un lugar perfecto para hacerlo.fuente
params
avance, para que sea más similar al original y más fácil de migrar?new Task("Param").execute()
másnew Task().execute("Param")
.Si desea utilizar el marco RoboGuice que le brinda otros beneficios, puede probar RoboAsyncTask, que tiene una devolución de llamada adicional onException (). Funciona muy bien y lo uso. http://code.google.com/p/roboguice/wiki/RoboAsyncTask
fuente
RoboGuice
Sigue vivo? ¿Parece que no se ha actualizado desde 2012?Hice mi propia subclase AsyncTask con una interfaz que define las devoluciones de llamada para el éxito y el fracaso. Entonces, si se lanza una excepción en su AsyncTask, la función onFailure pasa la excepción, de lo contrario, la devolución de llamada onSuccess pasa su resultado. Por qué Android no tiene algo mejor disponible está más allá de mí.
fuente
Una solución más completa para Cagatay Kalan continuación se muestra :
AsyncTaskResult
ExceptionHandlingAsyncTask
Tarea de ejemplo
fuente
Esta clase simple puede ayudarte
fuente
Otra forma que no depende del uso compartido de miembros variables es utilizar cancelar.
Esto es de documentos de Android:
Por lo tanto, puede llamar a cancelar en la instrucción catch y asegurarse de que onPostExcute nunca se llame, sino que onCancelled se invoca en el subproceso de la interfaz de usuario. Para que pueda mostrar el mensaje de error.
fuente
cancel(boolean)
resultando en una llamada aonCancelled()
existir desde el principio, peroonCancelled(Result)
se agregó en API 11 .En realidad, AsyncTask usa FutureTask & Executor, FutureTask admite la cadena de excepciones Primero definamos una clase auxiliar
Segundo, usemos
fuente
Personalmente, usaré este enfoque. Puede capturar las excepciones e imprimir el seguimiento de la pila si necesita la información.
hacer que su tarea en segundo plano devuelva un valor booleano.
Es como esto:
fuente
Otra posibilidad sería utilizarlo
Object
como tipo de retorno yonPostExecute()
verificar el tipo de objeto. Es corta.fuente
Si conoce la excepción correcta, puede llamar al
p.ej:
y vaya a "onProgressUpdate" y haga lo siguiente
Esto será útil solo en algunos casos. También puede mantener una
Global
Exception
variable y acceder a la excepción.fuente