(Mi dispiace per non essere stato così chiaro nel mio primo post)MVC in Android: applicazione o servizio per aggiornamenti asincroni?
Ecco la situazione: ho dati che devono essere aggiornati da Internet. Chiamiamolo Model
.
Che cosa voglio fare: Fondamentalmente suona come un modello MVC, in cui lo viene mantenuto anche nell'archiviazione locale (privata). Il Model
e i suoi metodi associati sono per applicazione. Ci sono diversi Activity
's che visualizzare e manipolare diversi aspetti di essa:
- utente naviga tra le varie
Activity
' s che visualizzanoModel
da diverse prospettive. Attualmente ho unoListActivity
per tutti gli elementi e unoActivity
per i dettagli di un elemento - A volte è necessario aggiornare
Model
. Sicuramente questo è fatto su un thread diverso. Il rinfresco può essere attivato da diversiActivity
. - Ci sono diversi (in termini di tempo) comuni compiti che possono essere attivati da diverse
Activity
's - miei carichi applicativi e salva
Model
all'ammasso privato quando inizia e si ferma
Il mio problema : Non sono sicuro di dove mettere Model
e le attività correlate in. Inoltre, non so quale meccanismo utilizzare per notificare Activity
di s. Attualmente mi vengono proposti 2 approcci:
- Utilizzare
Service
e inviare trasmissioni. Il salvataggio su disco viene eseguito inService#onDestroyed()
, quindi voglio ridurlo al minimo legandolo aActivity
. A questo punto, inoltre, non sono sicuro di come fornire le informazioni aggiornate: se fornire un getter inBinder
o includerlo nel messaggio di trasmissione. - Personalizzare l'oggetto
Application
in modo che i metodi di aggiornamento e siano disponibili in tutto il mondo. Quindi eseguo l'aggiornamento daActivity
utilizzandoAsyncTask
. Se ci sono altriActivity
che sono dietro l'attualeActivity
, si aggiorneranno inonResume()
quando l'utente torna indietro.
ragioni che non sto usando una classe con metodi statici:
- ho bisogno di salvare e archiviare
Model
su disco. - Alcuni dei metodi hanno bisogno di un contesto per la visualizzazione di brindisi, le notifiche, la cache, ecc
Inoltre, non metto queste funzionalità in un Activity
, perché ci sono diverse attività che manipolano lo stesso pezzo di dati persistenti.
qui sotto sono pseudocodice che illustrano ciò che voglio dire:
Uso del servizio:
/** 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());
}
}
};
}
Fai la funzionalità globalmente accessibile nell'oggetto Application personalizzato
/** 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();
}
}
debolezze che posso pensare per l'approazione Service
ch è la complessità, poiché Binding è asincrono. Ed è molto probabile che devo ripetere qualche codice, perché ho sia ListActivity
e Activity
Per l'approccio Application
, la documentazione dice di non fare affidamento su onTerminate()
essere chiamato.
So che sono molto imbarazzante. Qual è il modo convenzionale per risolvere questo tipo di problema?
Molte grazie.
È stata colpa mia per non essere stato chiaro. Ho diverse attività che accedono e mutano lo stesso pezzo di dati applicativi :) – Phil
Ho editato il mio post. Spero che non sia troppo prolisso. – Phil