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.
- ¿Utilizando Inyección de Dependencia con Roboguice?
- ¿Cómo abrir NavigationDrawer sólo al inicio de la primera aplicación?
- Adaptador genérico para muchos tipos de fila de presentación de listview en android
- Posibles patrones en la matriz 3x3 de los números
- Cómo obtener el patrón NullObject con RxJava
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?
- Android: cómo crear un fondo de patrón?
- Uso del servicio como singleton en Android
- ¿Cómo compartir datos entre dos presentadores en la arquitectura MVP en Android?
- ¿Hay alguna clase en Java similar a android.os.Handler en Android?
- Patrón de pincel personalizado de Android / imagen
- ¿Es Android BaseAdapter un ejemplo de patrón de adaptador?
- Patrón MVC en Android
- ¿Cuál es el principio del patrón de diseño en el desarrollo de Android?
+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); }
- La función seekTo () no funciona en VideoView
- PreferenceScreen – <intention … /> – Excepción – FLAG_ACTIVITY_NEW_TASK