Monthly Archives: May 2019

Why you shouldn’t use singleton on Android

A singleton is a common pattern frequently used in object oriented programming. Despite its good or bad reputation (depending on which side of the fight you are), it can leads to unsuspected issues when used in Java on Android platform. In this article we’ll explain what is a singleton and what are the issues you could face on Android.

What is a singleton ?

A singleton is a common pattern used in object oriented programming to ensure there’s only one instance of an object during the program lifetime.

public final class Singleton {
    // The unique object instance.
    private static final Singleton instance = new Singleton();

    private Singleton() {
        // Initialize your object here.
    }

    // A way to retrieve the unique instance from anywhere in your app.
    public static Singleton getInstance() {
        return instance;
    }
}

Then you can retrieve the instance anywhere in your code with something like:

...
Singleton myInstance = Singleton.getInstance();
...

You can have more details about the pattern and its usage here.

What is the problem with singletons on Android ?!

To understand the problem correctly we have to understand how a singleton instance is created and then destroyed. The instance creation is the easy part : as soon as you use the class (with Singleton.getInstance()) the class loader fetches the class and, if not done previously, initializes the static fields. Here it means executing new Singleton(). A new instance of the object is allocated then initialized and its reference stored in the instance field.

How is it destroyed then ? Theoretically the instance should be “garbage collected” when the last reference on it is released. But in the singleton case, the reference is held by the Singleton class itself, and the class is held by the class loader itself. So when does the last reference is released ?!

On a standard environment (let’s say Java program running on a computer), this reference would be released when the class loader is destroyed, either voluntarily or when the program quits.

On Android, the situation is different because you can’t predict when the class loader will be destroyed. As mobile devices are less powerful (or need to save energy), Android tries to optimize application start. Thus the Java virtual machine is loaded once in the application process and rarely stopped/destroyed. Usually it happens when the application crashes, is stopped because of memory pressure or when the phone shutdowns/reboots.

It is where it interacts with singletons. Every application component Application, Activity or Service provides one entry and one exit points:

class ... extends {Application, Activity, Service} {
    public void onCreate() { ... }
    public void onDestroy() { ... }
}

Regarding your application point of view, even if all the components of the app went through the onDestroy() exit point (in other words the application is gone, finished, …), the class loader is not destroyed. It means that all the singleton instances will stay in the state you left them. Contrary to what we expect, a singleton in an Android application leaves across components but also across multiple (but not all and not in a predictable way) application life cycles. It means that your standard Java singletons won’t be in brand new clean state as you could expect.

Conclusion

Be very careful when you use the singleton pattern on Android because it may retain a wrong state between two “runs” of your application. Android provides multiple ways to share states and information across Application, Service and Activity instances. I would recommend you to read the documentation carefully and use them instead of singletons.