Exploring Jetpack DataStore in Android

In this article we will learn about DataStore which is a new data storage solution in Android Jetpack.

Vivek Singh
ProAndroidDev

--

Image Source: Android Jetpack official page

Ever since the release of Android Jetpack it has come up with several libraries which makes us writing better Android code, avoid boilerplate code, etc. and now this time it has brought us an another awesome library called DataStore which according to official blog aims to replace the SharedPreferences API which has several drawbacks.

DataStore is a storage solution which is built on Coroutines and Flow to store data asynchronously. DataStore allows us to either store data in key-value pairs much like SharedPreferences or in typed objects which are backed by protocol buffers.

SharedPreferences vs. DataStore

  • DataStore provides asynchronous API for storing and reading data, while SharedPreferences provides async API only while reading changed values with the use of listeners.
  • DataStore is safe to call on the UI thread. It uses Dispatchers.IO under the hood.
  • DataStore is safe from runtime exceptions, while SharedPreferences can throw parsing errors in runtime exceptions.
  • Proto DataStore provides better type safety out of the box.
Image Source: Android Developers Blog

Types of DataStore

Jetpack provides two implementations of DataStore:

  • Preferences DataStore— It stores data in a key-value pairs like SharedPreferences but does not provide any type safety.
  • Proto DataStore — It store data as custom objects. It provides type safety out of the box, but it requires you to specify a scheme using protocol buffers.

In this article we will learn about the Preferences DataStore.

Setup Your Project

As working with any library, first you need to add a dependency in your app level build.gradle file.

dependencies {
// Preferences DataStore
implementation "androidx.datastore:datastore-preferences:1.0.0-beta01"
}

Currently, the DataStore library is in the beta stage, but you can always get the latest version from the official docs.

Saving Data in DataStore

Suppose you are creating a music application and you want to save the id of the last music played by the user, so that the user can find the last played song when he opens the app again after some time.

For this, we will create a class MusicPreferences where we will handle all the preferences set by the user.

MusicPreferences.kt
  • The MusicPreferences class will require the Context object to create the DataStore.
  • We can create our DataStore with the preferencesDataStorefunction of the Context object. We need to set the name of our datastore with the mandatory name parameter.
  • You need to define a key for each int value to save with the intPreferenceesKey() function. You also need to define the name of the key with name parameter.
  • We can create a function to save the song id in the DataStore. The DataStore provides a edit() method to save the value. We can pass the key and value to the MutablePreferences in the trailing lambda. Note that the edit() function is a suspend function.
  • Now you can get the saved preferences from the datastore with datastore.data which returns a Flow<Preferences> and with the .map{} operator we can can get the Flow<Int> which is our song id by passing the right key into the preferences.

Now in your ViewModel or activity/fragment whenever you want to save the song id into the DataStore, you just need to call our suspend function saveLastPlayedSongID() from a coroutine.

MusicViewModel.kt

In order to get the saved song id in the activity from the DataStore we can change the get the Flow<Int> and observe it after changing to LiveData with .asLiveData().

Now, as we have exposed the song id as a Flow, it will emit the values each time the song id is updated or edited in the datastore and the last played song will be updated accordingly.

Conclusion

The DataStore library comes up with many benefits over the SharedPreferences API such as supporting coroutines and flows. It reads and writes the data asynchronously which makes it safe to call on the UI thread and it also has an error signalling mechanism, whereas SharedPreferences has several drawbacks such as not safe to call on the UI thread and has an asynchronous API. DataStore is an excellent replacement that solves most of the problems with SharedPreferences.

--

--