Hello DataStore, Bye SharedPreferences👋 — Android📱 — Part 2: Proto DataStore

In this article series, we’ll learn how to use the Proto DataStore for storing type based objects. DataStore is the latest Android Jetpack 🚀 library which will replace SharedPreferences.

Shreyas Patil
ScaleReal
Published in
4 min readSep 12, 2020

--

Welcome Android Developers 👋. In the previous article, we saw how to use Preference DataStore to store key-value pairs. But it is not type-safe, Right? We’ll be covering that part in this article 😃. If you missed the previous article then you can read it 👇

What is Proto DataStore? 🤷‍♂

  • It stores instances as custom data.
  • Defines schema using Protocol buffers.
  • They are faster, smaller, simpler, and less ambiguous than XML and other similar data formats.

That’s enough introduction for Proto DataStore to get started… It’s time to write some code👨‍💻😎.

Let’s begin code 👨‍💻

You can simply clone or refer this repository to get example code demonstrating DataStore.

What we’ll be implementing? So we’ll be developing a Food app 😋 where a list of food items will be displayed and we’ll provide a filter to the user for food preference options. Like Food type as 🟢VEG or 🔴NON-VEG and Food taste as SWEET or SPICY 😋. So that user can filter his favourite food according to his choice. You can see a demo here. This is how it’ll be look alike👇.

An example application using Proto DataStore

Ok great! You might have got the idea of this app. First of all, we’ll need to add some dependencies for proto DataStore 👇

Add plugin and dependencies

Open build.gradle of your app module and add plugin at the top of the file and proto Datastore, Google Protobuf dependencies and then configure protobuf.

As you have seen above, we’ll have a list of food items. So let’s create a model for Food

Here we’ll also create another class i.e. UserFoodPreference which will be stored in DataStore. This model will be provided (or exposed) whenever preference is changed.

As you can see 👆 We’ve kept field nullable which means if they’re null then we can assume that user hasn’t set any filter or preference for food.

Define Protobuf

  • Now we can’t directly store this model as it is using Proto DataStore. We’ll need to define a schema in a proto file.
  • Create a new file called food_preference.proto in the path app/src/main/proto as following 👇 (See this for syntax guide).

As you can see 👆, we have created a schema in proto.

Whenever a value is not specified then XXX_UNSPECIFIED will be the default value here.

Once you’re done with the above step, Rebuild your Gradle project. You’ll see that FoodPreference.java will be automatically generated from the above proto schema.

Make Serializer for Proto class

You’ll need to create a serializer for your proto generated class. Because Proto DataStore requires serializer field which serializes/deserializes proto objects. You can create it as follows 👇

Create Food Preference Manager

Great! Now we’ll set up our Food Preference Manager which will store user food preferences (where we’ll actually implement Proto DataStore). Create a new class — FoodPreferenceManager. Here you’ll need to provide a filename for DataStore as well as serializer object for proto which we created recently.

Now we’ll create two functions for setting or changing preferences.

  • For Food type preference
  • For Food taste preference

As you can see in the above methods. We have mapped our FoodType or FoodTaste to the proto generated enums. That’s all about setting or changing preferences.

Now we’ll need to expose a Flow for observing user food preferences. We’ll map DataStore preferences to the data class which we earlier created i.e. UserFoodPreference.

That’s all about FoodPreferenceManager 😃. Now let’s implement it in our UI.

Set up Activity

Here I’ll assume that you’re implementing this app with RecyclerView in Activity and you’ve implemented ViewModel for getting data i.e. list of food items from Repository. (For demo purposes, here I’ve created a sample DataSource which gives a dummy list of food items). So I’ll directly show you implementation related to DataStore. You can refer to this class for more information.

So let’s make Activity

Note: Here foodListAdapter is a RecyclerView.Adapter’s implementation

Now, whenever Chips are clicked by the user then preferences should be stored or updated in DataStore. So let’s do that 👇

Now we should be able to observe the changes in food preference so that we can filter the list accordingly. We already had exposed a Flow which gives us UserFoodPreference whenever it’s updated. So it’s time to use that 👀.

Note: Here we have used asLiveData() extension function of Flow. Otherwise, we can also use lifecycleScope. This is generally useful when we’re actually implementing with ViewModel.

Now the implementation of filterFoodList() should look like follows 👇

Yeah! That’s it 😍. We have implemented Proto DataStore now. If you run the app, you’ll see the output as you have seen at the starting of this article 🚀.

So that was about Proto DataStore. I hope you enjoyed this article or liked it! 😃.

Thank you! 😃

--

--

Shreyas Patil
ScaleReal

Google Developer Expert for Android, 👨‍💻Engineer @ Paytm ❤️ Android & Kotlin | More info: https://shreyaspatil.dev