Using the Android Application Class to Persist Data

Using the Android Application class to persist data

I don't think 500kb will be that big of a deal.

What you described is exactly how I tackled my problem of losing data in an activity. I created a global singleton in the Application class and was able to access it from the activities I used.

You can pass data around in a Global Singleton if it is going to be used a lot.

public class YourApplication extends Application 
{
public SomeDataClass data = new SomeDataClass();
}

Then call it in any activity by:

YourApplication appState = ((YourApplication)this.getApplication());
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here.

I discuss it here in my blog post, under the section "Global Singleton."

How to save data stored in Application Class

Create a method saveData() in your singleton and then call it in the activity onPause().

Activity class dont have methods such onDestroy() and onPause().

Persisting state in the android Application class

It is better to not depend on the Application class unless you need to load some data, before anything else is started. Android can kill your process at any time to free resources, so your app should be able to handle this. Save all of your data in a snigleton class, and load it lazily -- check for null, and if so load on first access. It the state needs to be persistent, consider staving it file/shared prefs. If not, your app can probably live without it, so just make sure you check for null, etc.

Generally, you should persist state when activities become inactive -- onStop(), onPause(), but you can save as soon as it makes sense (e.g., the user has entered all required data). Spin off an AsyncTask to save data in the background and let the user continue their work.

Application class can be used for store data? (persistent data)

No it can not. If you don't store your data in storage (that doesn't need to be a db, could be a flat file or whatever) then it is not persistent.

Android Application class lifecyle documentation

I can't find an official documentation telling me that yes, the Application class can be killed on low memory.

Below are the references to where it's been stated:

  • Application Fundamentals
  • Processes and Threads
  • Multitasking the Android Way

I can't find any official diagram representing the Application lifecycle neither.

This is a reasonable observation... Although the following is opinion-based, my best guess is that such a diagram would contradict the Android's multitasking "philosophy" as described in the last reference provided:

"A key to how Android handles applications in this way is that processes don't shut down cleanly. When the user leaves an application, its process is kept around in the background, allowing it to continue working (for example downloading web pages) if needed, and come immediately to the foreground if the user returns to it. If a device never runs out of memory, then Android will keep all of these processes around, truly leaving all applications "running" all of the time."

I can't find any proper callback to use when the Application class is killed excepted onLowMemory(). Does it mean that I have to use this method to persist my data?

Regarding onLowMemory() whose description is quite straightforward, are we talking about a background process or foreground UI?...

If none of application Activities is in foreground and OS is low on memory, it may kill the app so that none of the Application's or the app component's (Activity, Service) callbacks will be invoked. That said, (since you're dealing with Activities) I recommend to store all persistent data as per the documentation, in onPause().

If the Application class is killed on low memory pressure and the app comes to foreground again, how can I know in its onCreate() that the app has been recreated after a system kill?

You can't recognize it in Application's onCreate().

When to use and not to use the android Application class?

Shared constants like ID's, pref key names, etc.

I generally create a constants file called C for this, as its better for readability. C.SHARED_PREFS is easier to understand that Application.SHARED_PREFS IMHO.

Global variables (i.e. setters/getters) reflecting current UI state,
navigation, selected fragment, and, in general, temporary data that
does not need to be persisted.

This would be better off in the Activity or component which it concerns (for example, the UI state of an Activity should probably stored in the icicle bundle, or within that instance of the Activity).

Hooks for persisting data when certain conditions are triggered.

This should be fine.

Updating the UI after preference changes.

Again, I feel this would be better off in the respective component.

Providing an easy way to access the context from anywhere in the app,
including code where getApplication() is not available, e.g. via a
static getter such as MyApp.getApp().

This would work, but be careful of memory leaks. You should generally pass the context in as a parameter when calling the method from an Activity or Service or whatever. Less chances of a memory leak.

Common methods that need the visibility of the global state variables
and which would become too cumbersome to move away to dedicated
classes.

I feel it would be better to make the effort of dedicated classes, as when your app grows in features and size, this will become difficult to maintain.

Why extend the Android Application class?

Offhand, I can't think of a real scenario in which extending Application is either preferable to another approach or necessary to accomplish something. If you have an expensive, frequently used object you can initialize it in an IntentService when you detect that the object isn't currently present. Application itself runs on the UI thread, while IntentService runs on its own thread.

I prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences. There are also ways to pass data from a Fragment to its parent Activity using interfaces.

Store data in Application class when I open application second time

public Double getGrandTotal() {
if (grandTotal == 0) {
SharedPreferences sharedPreferences = getSharedPreferences("config", Context.MODE_PRIVATE);
String value = sharedPreferences.getString("grandTotal", "0");
grandTotal = Double.valueOf(value);
}
return grandTotal;
}

public Double setGrandTotal(Double grandTotal) {
this.grandTotal = grandTotal;
SharedPreferences sharedPreferences = getSharedPreferences("config", Context.MODE_PRIVATE);
sharedPreferences.edit().putString("grandTotal", String.valueOf(grandTotal)).apply();
return grandTotal;
}

public Double grandTotal = 0.0;


Related Topics



Leave a reply



Submit