Patrón para reutilizar Android AsnycTask sobre varias actividades?

Tengo varias subclases de Actividad en mi proyecto, cada una de ellas llamando a un servicio web basado en SOAP, procesando y mostrando los resultados. La serialización SOAP, el manejo de llamadas y el análisis de resultados en varios objetos POJO se encapsula en la clase MyWebService. Esta clase ejecuta las llamadas de servicio web reales a través de una AsyncTask.

Para poder devolver los resultados a la subclase de actividad de llamada, calculé que todas estas actividades deben implementar una interfaz WebServiceResultProcessor, definiendo una sola función (processWebServiceResults) que actúa como una devolución de llamada para el AsyncTask, llamada desde onPostExecute.

También quiero mostrar un ProgressDialog durante la llamada de servicio web. Y aquí viene mi pregunta. Para poder mostrar el ProgressDialog (de MyWebService o AsyncTask), necesito pasar una referencia al Contexto de la actividad del llamador. Y para poder ejecutar la función de devolución de llamada desde AsyncTask, también necesito pasar la misma referencia de objeto, pero esta vez como WebServiceResultProcessor. Esto me parece un olor de código, pasando el mismo objeto dos veces, pero no puedo ver ninguna manera alrededor de eso. En lugar de crear una interfaz, podría crear una nueva clase base, extender la clase Activity y reforzar la herencia de la clase de extensión, pero eso significaría que excluiría ListActivity y los gustos de usar esta clase MyWebService.

¿Hay una mejor manera de hacer esto?

+1, una buena pregunta!

Esto no es una respuesta directa a su pregunta. Sin embargo, permítanme decir que creo AsyncTask no es una opción correcta para esas cosas. Pienso así porque en este caso AsyncTask contiene una referencia a una Activity (vía la instancia de ProgressDialog o los callbacks a ser llamados de onPostExecute() ).

Imagínense: en Android el sistema operativo puede matar a la Activity antes de AsyncTask ejecuta su doInBackground() . Esto es, por supuesto, una especie de caso de esquina, pero no es imposible. Considere un escenario: el usuario recibe una llamada entrante, su actividad se vuelve invisible, el sistema operativo necesita algo más de RAM y por lo tanto decide matar su actividad. Un caso de fugas de memoria, al menos.

No sé por qué Google literalmente oculta la información sobre cómo la interfaz de usuario debe estar correctamente separada de las tareas de fondo. Sí, dicen "usar un servicio". Pero no es una empresa trivial. Es una lástima que Google proporcione buenas guías para casi todos los temas de desarrollo, pero no en este. Sin embargo, puedo sugerir para comprobar la " Google I / O 2010 – Aplicaciones de cliente REST Android " presentación de inspiración. Parece que dieron una clave sobre cómo estas cosas deberían hacerse en Android.

Usted puede echar un vistazo a este artículo de blog ( parte 1 y parte 2 ), que implementa un servicio web con AsyncTaskLoader y el mismo servicio web con un componente de servicio. Además, muestra las diferencias entre ambos enfoques y también hay comentarios interesantes al artículo.

A pesar de la advertencia de Arhimed, terminé usando AsyncTask, ya que todavía se ajusta a mis propósitos. Sólo me aseguro de que todas las Actividades que onDestroy() servicios web, en su onDestroy() , envíen una cancel() a la asyncTask invocada. La implementación de AsyncTask por sí misma gestiona con gracia la solicitud de cancelación comprobando isCancelled () en todas partes donde sea necesario.

En cuanto a la pregunta original, debo haber tenido un lapso – la solución es realmente simple. Paso la instancia de subclase de actividad como un objeto a AsyncTask y lo moldeo a Contexto oa WebServiceResultProcessor, según sea necesario. Fragmentos que muestran cómo funciona:

 if (callerActivity instanceof Context) { ProgressDialog dialog = new ProgressDialog((Context)callerActivity); } 

 if (callerActivity instanceof WebServiceResultProcessor) { ((WebServiceResultProcessor)callerActivity).processWebServiceResults(soapObject); } 
  • Métodos estáticos o singleton, ¿cuál elegir?
  • ¿Es IntentService una implementación del patrón de comandos?
  • Patrón de Android AsyncTask / doInBackground
  • ¿Qué patrón de diseño es bueno para el desarrollo de aplicaciones Android
  • ¿Hay un patrón de diseño para reducir la duplicación de código cuando subclases Actividades en Android?
  • Parcelable y herencia en Android
  • Buenos patrones de diseño para codificar muchas solicitudes HTTP en Android
  • ¿Por qué algunos métodos del SDK de Android aceptan una matriz como parámetro en lugar de devolver una matriz?
  • ¿Debería el renderingThread de un SurfaceView tener el mismo ciclo de vida que la vista o la actividad?
  • Android.util.Log al publicar - ¿qué puedo hacer / no hacer
  • Mejores prácticas / patrones de diseño de codificación para Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.