Site icon Mobile App Development Services

Introduction to Jetpack DataStore – Alternative to SharedPreferences

Introduction

In mobile applications, some data has to be persisted to make the application startup faster, reduce network traffic or handle data completely offline. When we talk about data storage solutions for android, it is very common to think of SharedPreferences, it is a very simple/fast way of persisting data in our app and it has been here for a while, but now Jetpack DataStore comes as a possible replacement for SharedPreferences and it’s shortcomings.

In this article, we will be exploring Jetpack DataStore to store data in our Android application.

What is Jetpack DataStore?

Google’s definition:

“Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects with protocol buffers. DataStore uses Kotlin coroutines and Flow to store data asynchronously, consistently, and transactionally.”

DataStore provides 2 different implementations of Datastores:

In short, the first one is the same as how SharedPreferences work, it is simpler to implement but has no type-safety. The second one uses protocol buffers to serialize the data, it has a more complex implementation, but it comes with many advantages. 

Preferences vs Proto DataStore

The main objective of Proto DataStore is similar to Preferences DataStore, but the Proto DataStore is able to store objects with custom data types, it does not use key-value pairs like Preferences DataStore, just returns the generated object in a Flow. The generated object’s type and structure depend on the schema of the .protoc file.

A few key features of Proto DataStore over Preferences DataStore are as follows:

Proto DataStore vs Room

If Proto DataStore is able to store objects with custom data types then you might be thinking “What to use Proto DataStore or Room?” or “Why not use Room?”. Well if you use Room to save only user’s data, you need to create a database with a table, and also need to implement the query and insert functions. It sounds really inconvenient, so in this case, the Proto DataStore can be a hassle-free approach.

In this article, we will be discussing and focusing on the Preferences DataStore and how to implement it.

Why Jetpack DataStore?

“If you’re currently using SharedPreferences to store data, consider migrating to DataStore instead.” – by Google

DataStore aims to replace SharedPreferences as it is thread-safe and non-blocking. The concept behind DataStore is also quite similar to SharedPreferences, it uses key-value pairs to store data. Following are the benefits of using DataStore over SharedPreferences:

Implementation (Preferences DataStore)

It’s time to get into the implementation part and see how to use Preferences DataStore in our application.

Step 1: Dependencies

To use Jetpack DataStore in our application we have to add the dependency in our app-level build.gradle file:

implementation “androidx.datastore:datastore-preferences:1.0.0”

Step 2: Create a DataStore

To create a Preferences DataStore, we can use the preferenceDataStore delegate. The delegate will ensure that we have a single instance of DataStore with that name in our application.

Step 3: Create keys to the DataStore

Unlike SharedPreferences where you can use hard-coded string keys to write and read the data, DataStore requires key objects. We will need to create a key object and this is how we can create it:

This looks like an extra step but it is actually very helpful as your project becomes bigger, this will enforce developers to have all the keys in a centralized location.

You can also create other types of PreferenceKeys:

Step 4: Write data to the DataStore

Now that we have created our DataStore and PreferencesKey, it’s time to write data to the DataStore, we need to call the edit() method, let’s see how we can do that:

Step 5: Reading data from DataStore

To read the data from DataStore, we need to access the “data” property from the datastore, the data property is a Flow<Preferences>, so we can either get the entire preferences or map it into the value we actually want:

Step 6: Handle Exceptions

With the flow object we can also catch exceptions:

Migrating from SharedPreferences

In order to be able to migrate from SharedPreferences to DataStore, we need to update the datastore builder to pass in a SharedPreferencesMigration to the list of migrations. DataStore will be able to migrate from SharedPreferences to DataStore automatically, for us. Migrations are run before any data access can occur in DataStore. 

Import SharedPreferencesMigration from androidx.datastore.preferences

That’s it! It’s that easy to migrate your data from SharedPreferences to DataStore. 🙂

Conclusion

Ideally DataStore is best to use with Kotlin and especially with coroutines. We don’t need to worry about if our application uses standard SharedPreferences because migration is provided by the DataStore API.

Because of the fact that DataStore handles data migration, guarantees data consistency, and handles data corruption, it is worth changing from SharedPreferences to DataStore.

Feel free to share your responses and feedback below.

Thanks for reading!