2010-04-06 4 views
5

Tengo una tarea común que hago con algunas Actividades: descargar datos y luego mostrarlos. Tengo la parte de descarga abajo pat; es, por supuesto, un poco complicado debido a la posibilidad de que el usuario cambie la orientación o cancele la actividad antes de que se complete la descarga, pero el código está allí. Hay suficiente código manejando estos casos como para no tener que copiarlo/pegarlo en cada Actividad que tengo, así que pensé crear una subclase abstracta Actividad en sí misma de manera que maneje una única descarga de fondo que luego lanza un método que llena la página con datos.¿Existe un patrón de diseño para reducir la duplicación de código al crear subclases de Actividades en Android?

Todo esto funciona. El problema es que, debido a la herencia única, me veo obligado a recrear exactamente la misma clase para cualquier otro tipo de actividad; por ejemplo, uso Activity, ListActivity y MapActivity. Para usar la misma técnica para los tres, se requieren tres clases duplicadas, excepto que cada una amplía una Actividad diferente.

¿Hay algún patrón de diseño que pueda reducir la duplicación de código? Tal como está, ya he ahorrado mucha duplicación, pero me duele ver exactamente el mismo código en tres clases solo para que cada subclase tenga un tipo diferente de actividad.

Editar: Puesto que parece que necesito para ser un poco más específico ...

Supongamos que yo estoy tratando de resolver el problema de un fondo AsyncTask descarga durante los cambios de orientación. La solución que tengo ahora es usar devoluciones de llamada; hay un administrador de descargas que tengo que inicia estas descargas, y luego hago que Activity active una devolución de llamada. Cuando la orientación cambia, la actividad se destruye y luego se recrea; durante este proceso, desconecto la devolución de llamada de la actividad anterior y luego adjunto una nueva devolución de llamada de la nueva actividad.

Los cambios de orientación son un problema común, y en Actividades múltiples comienzo la Actividad con una vista de progreso mientras se cargan los datos. Lo que estoy tratando de resolver es no tener que volver a implementar esta lógica de manejo de la orientación diez veces; mi solución inicial fue subclasificar Actividad, pero luego obtuve el problema anterior.

Respuesta

3

Prefer composition over inheritance. Independientemente de lo que sea común, delegue en algunas clases que puedan ser miembros de Activity, ListActivity y MapActivity.

+0

Entiendo este concepto perfectamente, pero hacer composición en este caso significaría casi tanta duplicación de código como simplemente implementarlo en cada clase. Cada clase tendría que implementar onCreate(), onRetainNonConfigurationInstance(), onResume(), onPause(), onDestroy() y llamar al delegado. Preferiría no tener que pensar en este aspecto de implementación para cada actividad que escribo. Podría convencerme de lo contrario, pero en este caso la composición da como resultado tanta duplicación, a menos que me falte algo. –

+0

Ick. Eso sugiere que las Actividades de Android son demasiado grandes, y probablemente no tengas control sobre eso. Supongo que podría escribir una DelegatingActivity con esas funciones (y asignarDelegate() o somesuch) ya escritas, y heredar de eso. Como lo ha descrito hasta ahora, eso no tiene mucha ventaja sobre una simple intercalación de Actividad, pero podría dar sus frutos en el futuro. –

+0

La manera en que funcionan las actividades es que tienen diferentes métodos que se llaman en diferentes estados (por ejemplo, "onCreate()" y "onDestroy()"). Cuando implementa su propia actividad, sublima y extiende estos métodos para definir el comportamiento. Tu publicación me ha dado una idea, que es seguir creando múltiples subclases de diversas actividades, pero para que cada aplicación implemente un delegado dentro de ella; de esa manera no estoy implementando el mismo código cada vez. Aún así, esperaba una solución un poco menos desordenada. –

0

El problema es que está mezclando la vista y la lógica de su programa. Se ejecutará un hilo de fondo como AsyncTask mientras su aplicación no muera del sistema. Puede hacer la descarga de todo en la tarea asincrónica y luego guardarla en algún lugar de la tarjeta SD para recuperarla desde allí si está lista.

Puede subclase application class para mantener una referencia a la tarea o un controlador para comunicarse con la clase de cada actividad.

Si esto no es una solución a su problema en absoluto, tal vez podría aclarar la pregunta un poco. Ayudaría saber qué estás haciendo en los métodos onCreate ...

+0

Creo que ya tiene una visión limitada de lo que ya configuré. :) He escrito una biblioteca para descargar en segundo plano a través de AsyncTask, sin embargo, dicha biblioteca no puede dar cuenta de problemas como la destrucción/recreación de la actividad mediante cambios de orientación. Cuando la orientación cambie, tengo que poder volver a adjuntar la Actividad a la descarga que ya está en progreso (en mi caso, configurando una nueva devolución de llamada). El código que estoy tratando de reducir la duplicación es este código; cada actividad debe manejar cambios de orientación, y dado que es el mismo código entre cada uno, solo quiero reutilizarlo. –

+0

Todavía no entiendo lo que estás haciendo en todas las actividades onresume ondestroy etc., tal vez deberías dar algunos ejemplos de código – Janusz

0

No he utilizado MapActivity, pero he resuelto este problema al no usar ListActivity y proporcionar la funcionalidad en Activity. Realmente no hay mucho en ListActivity si miras: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/app/ListActivity.java Implementa la funcionalidad por ti mismo, obtienes más personalización y más espacio para crecer.

+0

Pensé en tu solución, pero de acuerdo con los documentos MapActivity no puede ignorarse de esta manera: "Una vista de mapa solo se puede construir (o inflar) mediante una MapActivity, ya que depende de los subprocesos que acceden a la red y al sistema de archivos en segundo plano, estos subprocesos deben guiarse por la gestión del ciclo de vida en MapActivity ". (http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MapView.html) –

+0

corect, me enfrenté al mismo problema y, de hecho, en lugar de ListAcivity utilicé mi OwnActivity con alguna implementación, pero con MapActivity todo lo que pude hacer fue copiar y pegar. la solución que finalmente utilicé, no porque sea bonita y limpia, sino porque es centralizar el código en un solo lugar, es usar una interfaz para mis necesidades de actividades básicas (en su caso onDownloadFinish, onDetachListener, onAttachListener etc ...) y tener una clase delegator implementar esos métodos, entonces cada actividad que necesita ese comportamiento también implementará esa interfaz y delegará todas las llamadas a ese objeto ... – codeScriber

0

¿Alguna manera de que tenga una clase de ayuda con métodos estáticos a los que pasaría sus actividades y realizaría el trabajo común allí en lugar de en cada actividad?

+0

Actualmente tengo algo así como esta configuración, aunque por la naturaleza de lo que estoy haciendo tiene que ser una Objetos instanciados no son métodos estáticos. Sin embargo, esta solución todavía significa que tiene que volver a escribir el mismo código en cada actividad que quiera usar esta funcionalidad, o debe subclasificar cada tipo de actividad para reducir la duplicación de código. –

Cuestiones relacionadas