Wednesday, July 19, 2017

Android Design Patterns: The Singleton Pattern

Android Design Patterns: The Singleton Pattern

What Is the Singleton Pattern?

The Singleton Pattern is a software design pattern that guarantees a class has one instance only and a global point of access to it is provided by that class. Anytime multiple classes or clients request for that class, they get the same instance of the class. This Singleton class may be responsible for instantiating itself, or you can delegate the object creation to a factory class.  

Let's use the example of a cellphone and its owner. A phone is typically owned by a single person, while a person can own many phones. Anytime one of these phones rings, the same owner picks it up. 

Benefits of the Singleton Pattern

In a typical Android app, there are many objects for which we only need one global instance, whether you are using it directly or simply passing it to another class. Examples include caches, OkHttpClientHttpLoggingInterceptorRetrofitGsonSharedPreferences, the repository class, etc. If we were to instantiate more than one of these types of objects, we'd run into problems like incorrect app behaviour, resource overuse, and other confusing results. 

Implementation

It's quite easy to implement this pattern. The following code snippet shows how a Singleton is created.

In the code above, we have a static variable INSTANCE to hold an instance of the class. We also made the constructor private because we want to enforce noninstantiability—the class can only instantiate itself. The method getInstance() guarantees that the class is instantiated, if it has not been, and that it's returned to the caller. 

Example: Creating a Single Instance of Retrofit

Retrofit is a popular library to connect a REST web service by translating the API into Java interfaces. To learn more about it, check out my tutorial here on Envato Tuts+. 

  • Android SDK
    Sending Data With Retrofit 2 HTTP Client for Android
    Chike Mgbemena

In an Android app, you'll need a single global instance of a Retrofit object so that other parts of an app such as a UserProfileActivity or SettingsActivity can use it to execute a network request without the need to create an instance every single time we need it. Creating multiple instances would pollute our app with unused retrofit objects, thereby occupying unnecessary memory on an already memory-constrained mobile device. 

So anytime client A calls RetrofitClient.getClient(), it creates the instance if it has not been created already, and then when client B calls this method, it checks if the Retrofit instance already exists. If so, it returns the instance to client B instead of creating a new one. 

Dealing With Multithreading

In the Android system, you can spin off multiple threads to perform different tasks. These threads can end up executing the same code block simultaneously. In the case of the Singleton class above, this could lead to the creation of multiple object instances, which violates the contract of a Singleton. So our Singleton code snippet method getInstance() is not thread safe. We'll now look at ways to make it thread safe.

Synchronize the getInstance() Method 

One of the ways to make the singleton code thread safe is by making the method getInstance() a synchronized one. Doing this only allows one thread to run the method at a time, forcing every other thread to be in a wait or blocked state. 

This approach makes our code thread safe, but it is an expensive operation. In other words, this can slow down performance. So you have to investigate and see if the performance cost is worthwhile in your application.

Eagerly Create an Instance

Another approach to deal with multiple threads accessing the singleton is to create the Singleton instance immediately when the class is loaded or initialized (by the Android ClassLoader in the Dalvik VM). This makes the code thread safe. Then the object instance will already be available before any thread accesses the INSTANCE variable. 

A drawback to this approach is that you can end up creating an object that might never be used, thereby occupying unnecessary memory. So this approach should typically only be used if you are sure that the singleton will be accessed. 

Bonus: Using Dagger 2

A dependency injection library such as Dagger can help you wire up your object dependencies and create singletons by using the @Singleton annotation. This will ensure that the object is only initialized once throughout the application lifecycle.

In the code above, we create a single instance of GsonCache, FileOkHttpClient and finally Retrofit types to be provided from the dependency graph generated by Dagger. 

To learn more about Dagger 2, check out our tutorial here on Envato Tuts+. 

  • Android SDK
    Dependency Injection With Dagger 2 on Android
    Kerry Perez Huanca

Conclusion

In this short tutorial, you learned about the Singleton pattern in Android: what it is, the benefits of using it, how to implement it by writing your own, and some ways of dealing with multiple threads. I also showed you how to use a third-party library such as Dagger 2. 

In the meantime, check out some of our other courses and tutorials on the Java language and Android app development!

  • Android SDK
    RxJava 2 for Android Apps: RxBinding and RxLifecycle
    Jessica Thornsby
  • Android SDK
    Practical Concurrency on Android With HaMeR
    Tin Megali
  • Android
    Ensure High-Quality Android Code With Static Analysis Tools
    Chike Mgbemena
  • Android SDK
    Create an Intelligent App With Google Cloud Speech and Natural Language APIs
    Ashraff Hathibelagal

No comments:

Post a Comment