2010-07-03 16 views
6

(Disculpa por no ser tan clara en mi primera publicación)MVC en Android: ¿aplicación o servicio para actualizaciones asincrónicas?

Aquí está la situación: Tengo datos que se actualizarán de Internet. Vamos a llamarlo 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 de aplicación. Hay varias Activity 's que mostrar y manipular los diferentes aspectos de la misma:

  • usuario navega a través de diferentes Activity' s que muestran Model desde diferentes perspectivas. Actualmente tengo un ListActivity para todos los elementos, y un Activity para los detalles de un elemento
  • A veces Model necesita una actualización. Seguramente esto se hace en un hilo diferente. La actualización se puede desencadenar desde varios Activity.
  • hay varios (tiempo) comunes tareas que se pueden activar desde distintos Activity 's
  • Mis aplicación carga y guarda Model al almacenamiento privado cuando empieza y se detiene

Mi problema : No estoy seguro de dónde poner Model y las tareas relacionadas en. Además, no sé qué mecanismo usar para notificar a Activity. Actualmente se me ocurren dos enfoques:

  • Use Service y envíe transmisiones. El guardado en el 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 proporcionar getter en Binder, o incluir eso en el mensaje de difusión.
  • Personalice el objeto Application para que métodos de actualización y getters estén disponibles en todo el mundo. Luego realizo la actualización desde Activity usando AsyncTask. Si hay otros Activity que están detrás del actual Activity, se actualizarán en onResume() cuando el usuario navegue hacia atrás.

razones que no estoy usando una clase con métodos estáticos:

  • que necesitan para guardar y almacenar Model en el disco.
  • Algunos de los métodos necesitan un contexto para la visualización de tostadas, notificaciones, el almacenamiento en caché, etc.

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

A continuación están ilustrando pseudocódigo lo que quiero decir:

Utilización 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 la funcionalidad accesible a nivel mundial en el objeto de aplicación personalizada

/** 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(); 
    } 
} 

debilidades que puedo pensar en la aproximación Service ch es complejidad, ya que Binding es asincrónico. Y es muy probable que tenga que repetir algo de código porque no tengo tanto ListActivity y Activity

Para el enfoque Application, la documentación dice no confiar en onTerminate() ser llamado.

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

Muchas gracias.

Respuesta

0

Bueno, podría extender un BroadcastReceiver en lugar de un Servicio, y cuando haya terminado de hacer lo que tiene que hacer, se carga una Actividad con los resultados.

+0

Fue mi culpa por no ser clara. Tengo varias Actividades que acceden y mutan la misma información de aplicación :) :) – Phil

+0

He editado mi publicación. Espero que no sea demasiado prolijo. – Phil

0

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

Estas tareas implican estados que necesitan a cargar y guardar correctamente cuando se inicia la aplicación y se detiene

Si ese es el caso, ¿por qué no haces un AsynTask dentro del Activity?

Tenía sus mismas preocupaciones sobre el envío de Intents con adentro pero tengo una aplicación que hace exactamente eso y no tengo problemas de rendimiento.

+0

Lo siento por no ser lo suficientemente claro. No lo puse en una Actividad porque tengo varias Actividades que acceden y mutan la misma información de aplicación. Edité mi publicación. – Phil

1

Service s lo general es apropiado para algo que no está unido a un solo Activity (y por lo general trabajar en conjunto con NotificationManager o una Widget). Esto no parece ser el caso.
Así que mi sugerencia es tener un bien por ingeniería AsyncTask que administra el estado a través de SharedPreferences/SQLite en sí (en lugar de abusar Applicaion) y será lanzado desde el ListActivity.

Cuestiones relacionadas