Understanding Protocol Buffers for Android Development
Learn about What, Why and How of Protocol Buffers for Android Development.
Why learn about Protocol Buffers?
As an Android Developer, you might have come across this term: Protocol buffers. What are these?
Android team at Google now advocates using Jetpack DataStore instead of SharedPreferences, as it offers several advantages like Asynchronous API, Error handling, migration support and data consistency etc.
Jetpack DataStore comes with two implementations :
- Preferences DataStore (Saves small Primitive Data in Key-Value pairs)
- Proto DataStore (Saves Small Typed Data backed by Protocol Buffers)
Defining a typed schema using Protocol Buffers in Proto DataStore provides additional type safety, which is missing in both traditional SharedPreferences and also Preferences DataStore.
What are Protocol Buffers?
Supported Languages
Protocol Buffers in Action in Android Studio
To work with Protocol Buffers, you need Protocol Buffer compiler. You can download and install it from this link, and later use command line.
Alternatively, as an Android developer, use Android Studio.
Create a new project in Android Studio using any of the available templates or you can also use any existing project in Kotlin.
Step 1: Add Dependencies
Add dependencies as below (Refer to this link for latest) to your app module’s build.gradle:
Step 2: Define the Schema in proto file
Suppose you have an app like JetTasks:
Here, you can use DataStore to save the boolean flag — for “Show Completed Tasks” and “Sort Order” which is an enum.
Create a new file called user_prefs.proto
in the app/src/main/proto
directory and paste the following code:
The definitions in a .proto
file are simple: you add a message for each data structure you want to serialize, then specify a name and a type for each field in the message.
Now, let’s understand above code line by line:
- syntax: proto3 language version lets you work with Kotlin.
- java_package: Defines the location, where generated Java files would reside.
- java_multiple_files: To tell whether to create separate file if there are multiple messages.
Some points to note about message:
- The “ = 1”, “ = 2” markers on each element identify the unique “tag” that field uses in the binary encoding.
- If a field value isn’t set, a default value is used: zero for numeric types, the empty string for strings, false for bools.
- You can also define
enum
types if you want one of your fields to have one of a predefined list of values.
Also, let’s consider a sample message as below (Don’t paste it in your code)
Here, as you can see in above code as explained at Android Developers Site:
- You can even define message types nested inside other messages.
- If a field is
repeated
, the field may be repeated any number of times (including zero). The order of the repeated values will be preserved in the protocol buffer. Think of repeated fields as dynamically sized arrays. - Tag numbers 1–15 require one less byte to encode than higher numbers, so as an optimization you can decide to use those tags for the commonly used or repeated elements, leaving tags 16 and higher for less-commonly used optional elements. Each element in a repeated field requires re-encoding the tag number, so repeated fields are particularly good candidates for this optimization.
Step 3: Rebuild the Project
Clean the project and Rebuild it. The UserPreferences
class is generated at compile time from the message
defined in the proto file. If you don’t see it generated, Invalidate caches and Restart .
You would see UserPreferences.java
as below:
Conclusion:
Term Protocol Buffers may sound a bit new and daunting, but it is indeed as simple as XML or JSON. If you like to learn more about it, here is the link:
You can use Kotlin Serialization to work with Proto DataStore, as alternative to Protocol buffers, more details here.
This post was exclusive about Protocol buffers, however in order to add Proto DataStore to your Android app, you need more steps, you can refer to Working with ProtoDataStore codelab or my app JetTasks at GitHub for reference.
Hope you enjoyed reading about Protocol buffers, if yes, please do leave a clap, that motivates me to write more about what I learn :)