Skip to content

Instantly share code, notes, and snippets.

@stevdza-san
Last active April 27, 2023 11:00
Show Gist options
  • Save stevdza-san/8b8276bff787b831340570a103d748f0 to your computer and use it in GitHub Desktop.
Save stevdza-san/8b8276bff787b831340570a103d748f0 to your computer and use it in GitHub Desktop.
Proto DataStore | YouTube Tutorial - https://youtu.be/5_Jy8Alcp14
plugins {
id "com.google.protobuf" version "0.8.12"
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.example.protodatastoretest"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// Proto DataStore
implementation "androidx.datastore:datastore-core:1.0.0-alpha01"
implementation "com.google.protobuf:protobuf-javalite:3.10.0"
// LifeCycle
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.10.0"
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
syntax = "proto3";
option java_package = "com.example.protodatastoretest";
option java_multiple_files = true;
message Person{
string firstName = 1;
string lastName = 2;
int32 age = 3;
}
package com.example.protodatastoretest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
mainViewModel.firstName.observe(this, {
textView.text = it.firstName
Log.d("FirstName", it.firstName)
Log.d("LastName", it.lastName)
Log.d("AgeName", it.age.toString())
})
save_btn.setOnClickListener {
val firstName = name_et.text.toString()
mainViewModel.updateValue(firstName, "Jovanovic", 25)
}
}
}
package com.example.protodatastoretest
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainViewModel(application: Application): AndroidViewModel(application) {
private val repository = ProtoRepository(application)
val firstName = repository.readProto.asLiveData()
fun updateValue(firstName: String, lastName: String, age: Int) = viewModelScope.launch(Dispatchers.IO) {
repository.updateValue(firstName, lastName, age)
}
}
package com.example.protodatastoretest
import androidx.datastore.CorruptionException
import androidx.datastore.Serializer
import com.google.protobuf.InvalidProtocolBufferException
import java.io.InputStream
import java.io.OutputStream
class MySerializer : Serializer<Person> {
override fun readFrom(input: InputStream): Person {
try {
return Person.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
override fun writeTo(t: Person, output: OutputStream) {
t.writeTo(output)
}
}
package com.example.protodatastoretest
import android.content.Context
import android.util.Log
import androidx.datastore.DataStore
import androidx.datastore.createDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import java.io.IOException
class ProtoRepository(context: Context) {
private val dataStore: DataStore<Person> = context.createDataStore(
"my_data",
serializer = MySerializer()
)
val readProto: Flow<Person> = dataStore.data
.catch { exception->
if(exception is IOException){
Log.d("Error", exception.message.toString())
emit(Person.getDefaultInstance())
}else{
throw exception
}
}
suspend fun updateValue(firstName: String, lastName: String, age: Int){
dataStore.updateData { preference->
preference.toBuilder().setFirstName(firstName).setLastName(lastName).setAge(age).build()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment