iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 25
1
Mobile Development

Kotlin Android Jetpack 系列 第 25

{Day25}DataStore-Proto DataStore

DataStore-Proto DataStore

Proto DataStore使用Protocol Buffers定義架構,只需要提供知存儲的類型。

protobuf type
double->double
float->float
int32->int
int64->long
bool->boolean
string->String

createDataStore(fileName = “資料庫名稱”,serializer = “序列化物件”):創建DataStore
DataStore.updateData:寫入資料
DataStore.data.map:將資料取出利用Flow傳回
Flow<T>.collect:取得資料

Gradle(Project)

dependencies {
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.13'
}

Gradle(Module)

apply plugin: 'com.google.protobuf'

dependencies {
    implementation  "androidx.datastore:datastore-core:1.0.0-alpha01"
    implementation  "com.google.protobuf:protobuf-javalite:3.10.0"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.10.0"
    }

    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java {
                    option 'lite'
                }
            }
        }
    }
}

在app/src/main/proto新增user_prefs.proto
設定完後先編譯

syntax = "proto3";

option java_package = "com.example.app_datastore";
option java_multiple_files = true;

message UserPreferences {
    string account = 1;
    string password = 2;
    bool remember = 3;
}

繼承Serializer 並把剛剛的UserPreferences導入

object UserPreferencesSerializer : Serializer<UserPreferences> {
    override fun readFrom(input: InputStream): UserPreferences {
        try {
            return UserPreferences.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override fun writeTo(t: UserPreferences, output: OutputStream) = t.writeTo(output)
}

創建Model

data class User(var account: String?, var password: String?, var remember: Boolean)

MainActivity

class MainActivity : AppCompatActivity() {

    //創建DataStore 
    private val dataStore by lazy {
        applicationContext.createDataStore(
            fileName = "user_prefs.pb",
            serializer = UserPreferencesSerializer
        )
    }

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

        //讀取數據 塞入Model
        CoroutineScope(Dispatchers.IO).launch {
            val user = dataStore.data.map { user ->
                User(user.account, user.password, user.remember)
            }

            withContext(Dispatchers.Main) {
                user.collect { user ->
                    account.setText(user.account)
                    password.setText(user.password)
                    remember.isChecked = user.remember
                }
            }
        }
    }

    //寫入數據
    private suspend fun putData(account: String, password: String, remember: Boolean) {
        dataStore.updateData { preferences ->
            preferences.toBuilder().setAccount(account)
                .setPassword(password)
                .setRemember(remember)
                .build()
        }
    }

    fun save(view: View) {
        CoroutineScope(Dispatchers.IO).launch {
            val account = account.text.toString()
            val password = password.text.toString()
            val remember = remember.isChecked
            putData(account, password, remember)
        }
    }
}


上一篇
{Day24}DataStore-Preferences DataStore
下一篇
{Day26}Activity
系列文
Kotlin Android Jetpack 30

尚未有邦友留言

立即登入留言