MVC on Android: an application or service for asynchronous updates?

(I apologize for the fact that in my first post it was not so clear)

Here is the situation: I have data that needs to be updated from the Internet. Let me call it Model .

What I want to do: Basically, it looks like an MVC model, where Model also stored in local (private) storage. Model and its associated methods are applied. There are several Activity that display and manipulate various aspects:

  • The user navigates through different Activity that display Model from different points of view. I currently have a ListActivity for all items, and an Activity for one item for details
  • Model sometimes needs updating. Of course, this is being done on a different topic. An update can be triggered by multiple Activity .
  • There are several (time-consuming) common tasks that can be run from different Activity
  • My application loads and saves Model to private storage when it starts and stops

My problem: I'm not sure where to put Model and its related tasks. In addition, I do not know what mechanism to use to notify Activity . I am currently coming up with two approaches:

  • Use Service and send broadcasts. Saving to disk is done in Service#onDestroyed() , so I want to minimize this by binding it to Activity . At this point, I also do not know how to deliver updated information: whether to provide getter in Binder or to include this in a broadcast message.
  • Customize your Application object so that update methods and getters are available worldwide. Then I upgrade from Activity using AsyncTask . If there are other Activity that are behind the current Activity , they will be updated in onResume() when the user goes back.

Reasons I do not use a class with static methods:

  • I need to save and save Model to disk.
  • Some of the methods need Context to display toasts, notifications, caching, etc.

In addition, I do not put these functions in the Activity , because there are several actions that control the same part of the persistent data.

The following are pseudo codes illustrating what I mean:

Use of service:

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

Make globally accessible functionality in a custom application object

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

The weaknesses that I can come up with for the Service approach is complexity, since the binding is asynchronous. And it is very likely that I should repeat some code, because I have both ListActivity and Activity

For the Application approach, the documentation says that you should not rely on the called onTerminate() .

I know that I am very embarrassed. What is the usual way to solve this problem?

Many thanks.

+6
android design model-view-controller service
source share
3 answers

Service is basically suitable for something that is not related to one Activity (and usually work together with NotificationManager or Widget ). This does not seem to be the case. Therefore, my suggestion is to have a well-designed AsyncTask that manages the state through the SharedPreferences / SQLite itself (instead of abusing Applicaion ) and will be launched from ListActivity .

+1
source share

Well, you can extend BroadcastReceiver instead of the Service, and when it does what it needs to do, it loads the Activity with the results.

0
source share

You have not explained what information you get, but this line is important:

These tasks include states that need to be loaded and saved gracefully when the application starts and stops

If so, why don't you make AsynTask inside an Activity ?

I had the same worries that you are sending Intents with an ArrayList inside, but I have an application that does just that, and I have no performance issues.

0
source share

All Articles