(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 muestranModel
desde diferentes perspectivas. Actualmente tengo unListActivity
para todos los elementos, y unActivity
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 variosActivity
. - 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 enService#onDestroyed()
, por lo que quiero minimizarlo vinculándolo aActivity
. En este punto, tampoco estoy seguro de cómo entregar la información actualizada: si proporcionar getter enBinder
, 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 desdeActivity
usandoAsyncTask
. Si hay otrosActivity
que están detrás del actualActivity
, se actualizarán enonResume()
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.
Fue mi culpa por no ser clara. Tengo varias Actividades que acceden y mutan la misma información de aplicación :) :) – Phil
He editado mi publicación. Espero que no sea demasiado prolijo. – Phil