(прошу прощения за то, что не так ясно в моем первом посте)
Вот ситуация: у меня есть данные, которые нужно обновить из Интернета. Давайте назовем это Model
.
Что я хочу сделать: По сути, это звучит как модель MVC, где Model
также сохраняется в локальном (частном) хранилище. Model
и связанные с ним методы являются прикладными. Есть несколько Activity
, которые отображают и манипулируют различными его аспектами:
- Пользователь
перемещается по различным
Activity
этот дисплей Model
с разных точек зрения. В настоящее время у меня есть ListActivity
для всех элементов и Activity
для деталей одного элемента
- Иногда
Model
нуждается в обновлении.
Конечно, это сделано в другом потоке. Обновление может быть вызвано несколькими Activity
.
- Есть несколько (отнимающих много времени) общих
задачи, которые можно запускать из разных
Activity
- Мое приложение загружается и сохраняется
Model
в частное хранилище при запуске
и останавливается
Моя проблема: Я не уверен, куда поместить Model
и связанные задачи. Кроме того, я не знаю, какой механизм использовать для уведомления Activity
. В настоящее время я придумываю 2 подхода:
- Используйте
Service
и отправляйте трансляции. Сохранение на диск выполняется в Service#onDestroyed()
, поэтому я хочу минимизировать это, привязав его к Activity
. На данный момент я также не уверен, как доставить обновленную информацию: предоставлять ли getter в Binder
или включить это в широковещательное сообщение.
- Настройте объект
Application
, чтобы методы обновления и getter были доступны глобально. Затем я выполняю обновление с Activity
, используя AsyncTask
. Если есть другие Activity
, которые находятся позади текущего Activity
, они обновятся в onResume()
, когда пользователь вернется назад.
Причины, по которым я не использую класс со статическими методами:
- Мне нужно сохранить и сохранить
Model
на диск.
- Некоторым методам нужен контекст
для отображения тостов, уведомлений, кэширования и т. д.
Кроме того, я не помещаю эти функции в Activity
, потому что есть несколько действий, которые управляют одним и тем же фрагментом постоянных данных.
Ниже приведен псевдокод, иллюстрирующий, что я имею в виду:
Использование службы:
/** 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());
}
}
};
}
Обеспечение общего доступа к функциональности в пользовательском объекте приложения
/** 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();
}
}
Слабые стороны, которые я могу придумать для подхода Service
, - это сложность, поскольку привязка асинхронна. И очень вероятно, что мне придется повторить некоторый код, потому что у меня есть и ListActivity
и Activity
Для подхода Application
в документации сказано, что не следует полагаться на onTerminate()
вызываемого.
Я знаю, что я очень неловкий. Как обычно решить эту проблему?
Большое спасибо.