<p>This blog is about Android Jetpack <span style="color: #000080;"><strong>Proto DataStore</strong></span> and how to implement Proto DataStore in our Android application.</p>



<div class="wp-block-buttons aligncenter is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link has-white-color has-text-color has-background" href="https://github.com/arunk7839/JetpackProtoDataStore" style="background-color:#520599" target="_blank" rel="noreferrer noopener"><strong>DOWNLOAD CODE</strong></a></div>
</div>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<amp-youtube layout="responsive" width="1200" height="675" data-videoid="E1cibpnHBC4" title="Android Jetpack Proto DataStore Example"><a placeholder href="https://youtu.be/E1cibpnHBC4"><img src="https://i.ytimg.com/vi/E1cibpnHBC4/hqdefault.jpg" layout="fill" object-fit="cover" alt="Android Jetpack Proto DataStore Example"></a></amp-youtube>
</div></figure>



<h3 class="wp-block-heading"><span style="color: #000080;"><strong><span id="Proto-DataStore">Proto DataStore</span></strong></span></h3>



<p><span style="color: #008000;"><strong>Proto DataStore</strong></span> ;stores data as objects of a custom data type. When using Proto DataStore, you have to define a schema using ;<a href="https://developers.google.com/protocol-buffers"><span style="color: #0000ff;"><strong><em>protocol buffers</em></strong></span></a>.</p>



<h3 class="p1 wp-block-heading"><span style="color: #000080;"><b>Creating New Project</b></span></h3>



<p>1 . Create a new project by going to <span style="color: #008000;"><b>File ;</b><span class="s1"><b>⇒</b></span></span><b><span style="color: #008000;"> ;New Android Project</span>,</b> select <span style="color: #008000;"><strong>Empty Activity</strong></span> , provide <span style="color: #008000;"><strong>app name</strong></span>, select language to <span style="color: #008000;"><strong>kotlin </strong></span>and then finally click on <span style="color: #0000ff;"><strong>finish</strong></span>.</p>



<h4 class="wp-block-heading" id="adding-dependencies"><span style="color: #000080;"><strong>Adding dependencies</strong></span></h4>



<p>2 . To work with Proto DataStore and get <span style="color: #008000;"><strong>Protobuf</strong></span> to generate code for our schema, we&#8217;ll have to make several changes to the <span style="color: #008000;"><strong>build.gradle</strong></span> file:</p>



<ul class="wp-block-list"><li>Add the <span style="color: #008000;"><strong>Protobuf</strong></span> plugin.</li></ul>



<pre class="wp-block-preformatted">plugins {
 id "com.google.protobuf" version "0.8.12"
}</pre>



<ul class="wp-block-list"><li>Configure <span style="color: #008000;"><strong>Protobuf</strong></span>.</li></ul>



<pre class="wp-block-preformatted">protobuf {<br> protoc {<br> artifact = "com.google.protobuf:protoc:3.10.0"<br> }<br><br> generateProtoTasks {<br> all().each { task ->;<br> task.builtins {<br> java {<br> option 'lite'<br> }<br> }<br> }<br> }<br>}</pre>



<ul class="wp-block-list"><li>Now add the below dependencies inside dependencies block. Once you have added all these, <span style="color: #0000ff;"><strong>sync</strong></span> your project.</li></ul>



<pre class="wp-block-preformatted">dependencies { 
 <span style="color: #008000;"><strong>// Proto DataStore</strong></span>
 implementation "androidx.datastore:datastore-core:1.0.0-alpha01"
 implementation "com.google.protobuf:protobuf-javalite:3.10.0"

 <strong><span style="color: #008000;">// LifeCycle</span></strong>
 implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
 implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
 implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
}</pre>



<h4 class="p1 wp-block-heading"><span style="color: #000080;"><b>Defining a Schema</b></span></h4>



<p class="p1">3 . To use Proto DataStore first we need to define a schema with proto file.</p>



<ul class="ul1 wp-block-list"><li class="li1">We will create a <strong><span style="color: #0000ff;">.proto</span></strong> file at ;<span style="color: #008000;"><strong>app/src/main/proto</strong></span> ; location. ;</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://c1ctech.com/wp-content/uploads/2021/03/Screen-Shot-2021-03-08-at-10.25.33-PM.png" alt="" class="wp-image-2404"/></figure></div>



<ul class="ul1 wp-block-list"><li>Now let’s define the schema.</li></ul>



<p><span style="color: #0000ff;"><strong>data.proto</strong></span></p>



<pre class="wp-block-preformatted">syntax = "proto3";<br><br>option java_package = "com.c1ctech.jetpackprotodatastore";<br>option java_multiple_files = true;<br><br>message Person {<br> string first_name = 1;<br> string last_name = 2;<br> int32 age = 3;<br> bool gender = 4;<br>}</pre>



<p>4 . Open your <strong><span style="color: #0000ff;">activity_main.xml</span>.</strong> To create the following UI, add the below code<strong>.</strong></p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="https://c1ctech.com/wp-content/uploads/2021/03/Screenshot_1615205061.png" alt="" class="wp-image-2398" width="409" height="727"/></figure></div>



<p><strong><span style="color: #0000ff;">activity_main.xml</span></strong></p>



<pre class="wp-block-preformatted"><;?xml version="1.0" encoding="utf-8"?>;<br><;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"<br> xmlns:app="http://schemas.android.com/apk/res-auto"<br> xmlns:tools="http://schemas.android.com/tools"<br> android:layout_width="match_parent"<br> android:layout_height="match_parent"<br> tools:context=".MainActivity">;<br><br> <;Button<br> android:id="@+id/btn_save"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_60dp"<br> android:background="@color/colorPrimaryDark"<br> android:padding="@dimen/padding_18dp"<br> android:text="Save user"<br> android:textColor="@android:color/white"<br> android:textSize="@dimen/textsize_15sp"<br> android:textStyle="bold"<br> app:layout_constraintEnd_toEndOf="@+id/switch_gender"<br> app:layout_constraintStart_toStartOf="@+id/switch_gender"<br> app:layout_constraintTop_toBottomOf="@+id/switch_gender" />;<br><br> <;EditText<br> android:id="@+id/et_lname"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_16dp"<br> android:ems="10"<br> android:hint="@string/hint_enter_last_name"<br> app:layout_constraintEnd_toEndOf="@+id/et_fname"<br> app:layout_constraintStart_toStartOf="@+id/et_fname"<br> app:layout_constraintTop_toBottomOf="@+id/et_fname" />;<br><br> <;EditText<br> android:id="@+id/et_age"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_16dp"<br> android:ems="10"<br> android:hint="@string/hint_enter_age"<br> android:inputType="number"<br> app:layout_constraintEnd_toEndOf="@+id/et_lname"<br> app:layout_constraintStart_toStartOf="@+id/et_lname"<br> app:layout_constraintTop_toBottomOf="@+id/et_lname"<br> tools:layout_editor_absoluteY="317dp" />;<br><br> <;EditText<br> android:id="@+id/et_fname"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_30dp"<br> android:ems="10"<br> android:hint="@string/hint_enter_first_name"<br> app:layout_constraintEnd_toEndOf="@+id/tv_gender"<br> app:layout_constraintStart_toStartOf="@+id/tv_gender"<br> app:layout_constraintTop_toBottomOf="@+id/tv_gender"<br> tools:layout_editor_absoluteY="178dp" />;<br><br> <;TextView<br> android:id="@+id/tv_fname"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_30dp"<br> android:textStyle="bold"<br> android:textColor="@color/colorPrimaryDark"<br> android:textSize="@dimen/textsize_20sp"<br> app:layout_constraintEnd_toEndOf="parent"<br> app:layout_constraintHorizontal_bias="0.5"<br> app:layout_constraintStart_toStartOf="parent"<br> app:layout_constraintTop_toTopOf="parent" />;<br><br> <;TextView<br> android:id="@+id/tv_lname"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_16dp"<br> android:textStyle="bold"<br> android:textColor="@color/colorPrimaryDark"<br> android:textSize="@dimen/textsize_20sp"<br> app:layout_constraintEnd_toEndOf="@+id/tv_fname"<br> app:layout_constraintStart_toStartOf="@+id/tv_fname"<br> app:layout_constraintTop_toBottomOf="@+id/tv_fname" />;<br><br> <;TextView<br> android:id="@+id/tv_age"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_16dp"<br> android:textStyle="bold"<br> android:textColor="@color/colorPrimaryDark"<br> android:textSize="@dimen/textsize_20sp"<br> app:layout_constraintEnd_toEndOf="@+id/tv_lname"<br> app:layout_constraintStart_toStartOf="@+id/tv_lname"<br> app:layout_constraintTop_toBottomOf="@+id/tv_lname" />;<br><br> <;TextView<br> android:id="@+id/tv_gender"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_16dp"<br> android:textStyle="bold"<br> android:textColor="@color/colorPrimaryDark"<br> android:textSize="@dimen/textsize_20sp"<br> app:layout_constraintEnd_toEndOf="@+id/tv_age"<br> app:layout_constraintStart_toStartOf="@+id/tv_age"<br> app:layout_constraintTop_toBottomOf="@+id/tv_age" />;<br><br> <;androidx.appcompat.widget.SwitchCompat<br> android:id="@+id/switch_gender"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> android:layout_marginTop="@dimen/margin_16dp"<br> android:text="@string/female_male"<br> android:textSize="@dimen/textsize_20sp"<br> app:layout_constraintEnd_toEndOf="@+id/et_age"<br> app:layout_constraintStart_toStartOf="@+id/et_age"<br> app:layout_constraintTop_toBottomOf="@+id/et_age" />;<br><br><;/androidx.constraintlayout.widget.ConstraintLayout>;</pre>



<h4 class="p1 wp-block-heading"><span style="color: #000080;"><b>Create a Proto DataStore</b></span></h4>



<p>5 . There are two steps involved in creating a Proto DataStore to store your typed objects:</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>




<p>1 . Create a class named <span style="color: #008000;"><strong>MySerializer</strong></span> ;and write the following code.</p>



<pre class="wp-block-preformatted">object MySerializer : Serializer<;Person>; {<br><br> override fun readFrom(input: InputStream): Person {<br> try {<br> return Person.parseFrom(input)<br> } catch (exception: InvalidProtocolBufferException) {<br> throw CorruptionException("Cannot read proto.", exception)<br> }<br> }<br><br> override fun writeTo(t: Person, output: OutputStream) {<br> t.writeTo(output)<br> }<br><br>}</pre>



<ul class="wp-block-list"><li class="p1">The class <span style="color: #008000;"><strong>My<span class="s1">Serializer</span></strong></span> implements <span class="s1"><span style="color: #0000ff;"><strong>Serializer</strong><strong><;Person>;</strong></span></span>, where <span style="color: #008000;"><strong><span class="s1">Person</span></strong></span> is the type defined in the proto file. This Serializer class tells DataStore how to read and write your data type.</li></ul>



<p>2. Create an instance of<span style="color: #008000;"><strong> <span class="s1">DataStore<;Person>;</span></strong></span>, where <span style="color: #008000;"><strong><span class="s1">Person</span></strong></span> is the type defined in the proto file ( <strong>data.proto</strong> ). ;</p>



<pre class="wp-block-preformatted"><strong>class </strong>PersonDataStore(context: Context) {
 <strong>private val dataStore</strong>: DataStore<;Person>;

 <strong>init </strong>{
 <strong>dataStore </strong>= context.<em>createDataStore</em>(
 fileName = <strong>"data.pb"</strong>,
 serializer = MySerializer
 )
 }
</pre>



<ul class="wp-block-list"><li class="p1"><span style="color: #0000ff;"><strong><span class="s1">filename</span></strong></span> ;:<span class="Apple-converted-space"> ; </span>tells DataStore which file to use to store the data.</li><li class="p1"><span class="s1"><strong><span style="color: #0000ff;">serializer</span></strong>: </span> ;tells DataStore the name of the serializer class.</li></ul>



<h4 class="p1 wp-block-heading"><span style="color: #000080;"><b>Read from a Proto DataStore</b></span></h4>



<p class="p1">Use ;<span style="color: #008000;"><strong><span class="s1">DataStore.data</span></strong></span> to read a <span class="s1">Flow</span> of the object or the appropriate property from your stored object.</p>



<pre class="wp-block-preformatted"><span style="color: #008000;"><strong>//reading Person object</strong></span>
val user: Flow<;Person>; = dataStore.data
 .map {
 it
 }

<span style="color: #008000;"><strong>//reading Person object property firstName</strong></span>
<strong>//val userName: Flow<;String>; = dataStore.data
 // .map {
 // it.firstName
 // }</strong></pre>



<h4 class="p1 wp-block-heading"><span style="color: #000080;"><b>Write to a Proto DataStore</b></span></h4>



<p class="p1">Proto DataStore provides an ;<span style="color: #008000;"><strong><a style="color: #008000;" href="https://developer.android.com/reference/kotlin/androidx/datastore/DataStore#updatedata"><span class="s1">updateData()</span></a></strong></span> function that  ;gives you the current state of the data as an instance of your data type (Person) and update the stored object.</p>



<pre class="wp-block-preformatted">suspend fun storeData(age: Int, fname: String, lname: String, isMale: Boolean) {<br> dataStore.updateData { preference ->; preference.toBuilder()<br>.setAge(age)<br>.setFirstName(fname)<br>.setLastName(lname)<br>.setGender(isMale).build()<br> }<br>}</pre>



<h4 class="p1 wp-block-heading"><span style="color: #000080;"><b>Using Proto Data Store</b></span></h4>



<p>6 . Open <span style="color: #008000;"><strong>MainActivity.kt</strong> </span>and add the below code.</p>



<pre class="wp-block-preformatted">package com.c1ctech.jetpackprotodatastore

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.Observer
import androidx.lifecycle.asLiveData
import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
 private lateinit var personDataStore: PersonDataStore
 var age = 0
 var fname = ""
 var lname = ""
 var gender = ""

 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)

 personDataStore = PersonDataStore(this)


 <strong><span style="color:#04603e" class="has-inline-color">//Gets the user input and saves it</span></strong>
 btn_save.setOnClickListener {
 fname = et_fname.text.toString()
 lname = et_lname.text.toString()
 age = et_age.text.toString().toInt()
 val isMale = switch_gender.isChecked

 <strong><span style="color:#04603e" class="has-inline-color"> //Stores the values</span></strong>
 lifecycleScope.launch {
 personDataStore.storeData(age, fname, lname, isMale)
 }

 }

 observeData()
 }

 private fun observeData() {

 personDataStore.user.asLiveData().observe(this, Observer {
 if (it != null &;&; it.age >; 0) {
 tv_fname.text = it.firstName
 tv_lname.text = it.lastName
 tv_age.text = it.age.toString()
 gender = if (it.gender) "Male" else "Female"
 tv_gender.text = gender

 } else {
 tv_fname.text = ""
 tv_lname.text = ""
 tv_age.text = ""
 tv_gender.text = ""
 }
 })
 }
}</pre>



<ul id="block-31495fd9-2e0f-4300-ab5b-50c597779adf" class="block-editor-rich-text__editable block-editor-block-list__block wp-block is-selected is-hovered rich-text wp-block-list"><li>In order to get the saved values in the activity from the DataStore, we need to change the <strong><span style="color: #008000;">Flow<;Person>;</span></strong> to LiveData with <strong><span style="color: #008000;">.asLiveData()</span> ;</strong>and observe it.</li></ul>


