- When developing Android applications, most of the time we need to share information (whether it be primitive data or complex objects) between different Activities. For example, we might want to pass in some data to initialise the views within a new Activity, or we might want to reuse a Database Helper across all our Activities to improve performance.
There are several different means of accomplishing this seemingly trivial task. However, picking the best option that suits your needs can be a daunting task for a novice Android developer! I aim to summarise few methods of sharing information between Activities and discuss when to use each one.
Firstly, we can classify the information we want to share into two categories:
- Persistent data – Information that need to be persisted across application restarts (e.g. when the application process is killed and restarted later).
- Non-persistent information – Information that is only needed while the application is alive.
Sharing of persistent data is a large topic in itself that uses techniques such as the use of Application Preferences, files, content providers and sql databases. I will leave a discussion on that to another day. The rest of the article will be focusing on how we can share non-persistent information.
Let us list different ways in which you can share information in Android. This list by no means is exhaustive, and feel free to recommend alternatives in the comments below. These include the use of:
staticfields and methods
- Singleton objects
- Background services
Intents are used mainly to pass primitive values (e.g. ints, longs, bytes etc) and few pre-defined objects (e.g. String, few types of arrays and Parcelables) when starting up new Activities or services.
// When starting a new Activity ('NewActivity')
// from within the current Activity
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("key_intVal1", 2 /* some int value */);
intent.putExtra("key_strVal1", "my string to new activity");
startActivity(intent); // starts the NewActivity
- Easy to pass primitives
- Can only pass limited types of complex objects (e.g. Strings, Parcalable, Serializable objects)
- Can pass complex-objects if they are Serializable, but incur a performance hit (during both marshalling and unmarshalling). Google suggests to use “A HashMap of WeakReferences to Objects with Long keys”, where the keys are unique (based on a counter or time stamp).
Each Android application can have at most one
android.app.Application associated with it. You are responsible for sub-classing the
Application Class, and it is used to maintain a global state of the application across all Activites. Conceptually, you can think of it as a non-static singleton its life cycle being managed by Android OS.
- Gives you complete control over the management of application life-cycle, so resources can be properly initialised and disposed of.
- Provides a single entry point where any Activity or Service within the application can gain access to the desired object
- Can only expose information to Activities and Services within the application
This is essentially exposing your object as a public static variable, so other classes can directly access it.
// within MyActivity.java
public static final MyObjectToShare MY_OBJECT
= new MyObjectToShare();
And then to consume that public static object:
- Quick and hacky way to experiment with your logic.
- Have to manually manage the life-cycle of the static object; specially if it consumes resources that needs to be freed before the application shuts down (e.g. a database helper). This is a non-trivial task when using only public static objects.
- Can encounter race conditions when accessing from different threads
- Hard to unit test
- Violates good OO principals
Similar to Application subclasses mentioned earlier, there is only a single instance of a singleton class exists in your application.
- Easy to refer to the singletons by directly calling the specific class, without having to use
getApplication()to obtain an Application subclass.
- The life cycle is not under your control. Therefore, need to have an Application class to initiate and tear down these static classes.
- Singleton classes are harder to unit test
Background services are useful when your application needs to perform tasks without the intervention of the user; such as listening to incoming streams of data during music playback etc. Unless you need to perform tasks in background quite often, this method is an overkill (performance-wise) for simply exchanging information between different Activities.
Hope this article helped you to get a better idea about different techniques of sharing information between Activities.