MVC en Android: ¿Aplicación o servicio para actualizaciones asíncronas?

(Lo siento por no ser tan claro en mi primer post)

Aquí está la situación: Tengo datos que deben ser actualizados de Internet. Vamos a llamar Model .

Lo que quiero hacer: Básicamente suena como un modelo MVC, donde el Model también se mantiene persistente en el almacenamiento local (privado). El Model y sus métodos asociados son aplicables a las aplicaciones. Hay varias Activity que muestran y manipulan diferentes aspectos de la misma:

  • El usuario navega a través de diferentes Activity que muestran el Model desde diferentes perspectivas. Actualmente tengo una ListActivity para todos los elementos, y una Activity para los detalles de un elemento
  • A veces el Model necesita refrescarse. Seguramente esto se hace en un hilo diferente. La actualización puede ser activada desde varias Activity .
  • Hay varias tareas comunes (que consumen mucho tiempo) que se pueden activar desde distintas Activity
  • Mi aplicación carga y guarda el Model en el almacenamiento privado cuando se inicia y se detiene

Mi problema: No estoy seguro de dónde poner Model y las tareas relacionadas. Además, no sé qué mecanismo utilizar para notificar la Activity . Actualmente tengo dos enfoques:

  • Utilice Service y envíe transmisiones. El almacenamiento en disco se realiza en Service#onDestroyed() , por lo que quiero minimizarlo vinculándolo a Activity . En este punto, tampoco estoy seguro de cómo entregar la información actualizada: si se debe proporcionar un getter en Binder o incluirlo en el mensaje de difusión.
  • Personalizar el objeto Application para que los métodos de actualización y getters estén disponibles globalmente. A continuación, realizar la actualización de Activity utilizando AsyncTask . Si hay otras Activity que están detrás de la Activity actual, se actualizarán en onResume() cuando el usuario vuelva a navegar.

Razones por las que no estoy usando una clase con métodos estáticos:

  • Necesito guardar y almacenar el Model en el disco.
  • Algunos de los métodos necesitan un Contexto para mostrar brindis, notificaciones, almacenamiento en caché, etc.

Además, no pongo estas funcionalidades en una Activity porque hay varias actividades que manipulan la misma pieza de datos persistentes.

A continuación se muestra un pseudocódigo que ilustra lo que quiero decir:

Uso del servicio:

 /** Service maintaining state and performing background tasks */ class MyService extends Service { Model mModel; Binder mBinder; onCreate() { super.onCreate(); mBinder = new Binder(); // load mModel from disk, or do default initialization } onDestroy() { super.onDestroy(); // save mModel to disk } onBind() { return mBinder; } class Binder { refresh() { new AsyncTask() { doInBackground() { // update mModel from Internet } onPostExecute() { sendBroadcasts(new Intent("my.package.REFRESHED")); } }.execute(); } getState() { return mModel.getState(); } } } /** Activity displaying result */ class MyActivity extends ListActivity { MyService.Binder mBinder; onCreate() { super.onCreate(); // register mReceiver // bind service } onDestroy() { super.onDestroy(); // unbind service // unregister mReceiver } /** Invokes time-consuming update */ refresh() { // binding is asynchronous, and user may trigger refreshing too early if (mBinder != null) { mBinder.refresh(); } } BroadcastReceiver mReceiver = new BroadcastReceiver() { onReceive(Intent intent) { if ("my.package.REFRESHED".equals(intent.getAction()) && mBinder != null) { updateViews(mBinder.getState()); } } }; } 

Hacer que la funcionalidad sea accesible globalmente en el objeto Application personalizado.

 /** Custom Application providing domain specific functionalities */ class MyApplication extends Application { Model mModel; onCreate() { super.onCreate(); // load mModel from disk, or do default initialization } onTerminate() { super.onTerminate(); // save mModel to disk } void refresh() { /** time-consuming */ } getState() { return mModel.getState(); } } /** Activity displaying result */ class MyActivity extends ListActivity { onResume() { super.onResume(); // in case some top Activities have refreshed // and user is navigating back updateViews(((MyApplication)getApplicationContext()).getState()); } /** Invokes time-consuming update */ refresh() { new AsyncTask() { doInBackground() { ((MyApplication)getApplicationContext()).refresh(); } onPostExecute() { // update the ListView according to result updateViews(((MyApplication)getApplicationContext()).getState()); } }.execute(); } } 

Las debilidades que puedo pensar en el enfoque de Service es la complejidad, ya que Binding es asíncrono. Y es muy probable que tenga que repetir algún código porque tengo ListActivity y Activity

Para el enfoque de Application , la documentación dice que no se debe invocar onTerminate() .

Sé que estoy siendo muy torpe. ¿Cuál es la forma convencional de resolver este tipo de problema?

Muchas gracias.

3 Solutions collect form web for “MVC en Android: ¿Aplicación o servicio para actualizaciones asíncronas?”

Service s son en su mayoría adecuados para algo que no está ligado a una sola Activity (y normalmente trabajan junto con NotificationManager o un Widget ). Esto no parece ser el caso.
Así que mi sugerencia es tener un AsyncTask bien diseñado que gestione el estado a través de SharedPreferences / SQLite sí (en lugar de abusar de Applicaion ) y se iniciará desde ListActivity .

Bueno, puedes extender un BroadcastReceiver en lugar de un Servicio, y cuando se hace lo que se necesita hacer, se carga una Actividad con los resultados.

Usted no explicó qué tipo de información está recibiendo, pero esta línea es importante:

Estas tareas implican estados que necesitan ser cargados y guardados con gracia cuando la aplicación se inicia y se detiene

Si ese es el caso, ¿por qué no hace un AsynTask dentro de la Activity ?

Tuve sus mismas preocupaciones acerca de enviar Intents con ArrayList dentro, pero tengo una aplicación que hace exactamente eso y no estoy teniendo problemas de rendimiento.

  • ¿Cómo actualizar un TextView en una actividad de un servicio en Android?
  • El servicio de fondo de Android se está reiniciando cuando se cancela la aplicación
  • ¿Cómo comprobar el permiso automático de MIUI mediante programación?
  • El servicio no se reinicia después de que "Clear Memory" + appWidget se bloquea
  • Cómo mostrar un cuadro de diálogo de un servicio
  • Adquisición de instancia del servicio de fondo
  • Android - widget de actualización sobre el servicio con datos de la red. ¿El mejor enfoque?
  • La llamada de servicio vuelve a la actividad en android
  • Recolector de datos de sensor de fondo en Android
  • ¿Cómo reiniciar automáticamente un servicio incluso si la fuerza del usuario lo cierra?
  • cómo abrir la configuración de accesibilidad de mi aplicación directamente?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.