一文了解DataStore(Proto)

前言

  1. 本篇主要介绍Proto DataStore的内容。
  2. 如果还不了解DataStore,请参考上篇一文了解DataStore(Preferences)
  3. 本篇会涉及到Protocol Buffers相关的内容,如果不太了解,可以查资料作以了解。

准备工作

1. 插件引入:
plugins {
    id "com.google.protobuf" version "0.8.17"
}

    protobuf {
        protoc {
            artifact = "com.google.protobuf:protoc:3.14.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'
                    }
                }
            }
        }

    }


2. 依赖引入
    implementation 'androidx.datastore:datastore:1.0.0'
    implementation 'androidx.datastore:datastore-preferences:1.0.0'
    implementation  "androidx.datastore:datastore-core:1.0.0"
    implementation  "com.google.protobuf:protobuf-javalite:3.18.0"
3. proto编写及编译
  • proto文件目录src/main/proto
  • proto内容如下:
#固有的 使用proto3
syntax = "proto3";
# 固有   将edu.test.demo改为自己的包名
option java_package = "edu.test.demo";
option java_multiple_files = true;

# 内容定义 UserPreferences 为类名
# 字段格式为  类型 字段名 = 编号 ,注意此处编号需要唯一。
message UserPreferences {
    string name = 1;
    int32 age = 2;
    float weight = 3;
    float tall = 4;
    int32 sex = 5;
}
  • 完成之后进行编译项目,即可生成相关的文件,生成文件以下目录:
    app/build/generated/source/proto/debug/包名/
    如下图所示:
    proto生成的文件
4. 编写序列化类
代码如下:
object UserPreferencesSerializer:Serializer<UserPreferences> {
    override val defaultValue: UserPreferences
        get() = UserPreferences.getDefaultInstance()

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

    override suspend fun writeTo(t: UserPreferences, output: OutputStream) {
        t.writeTo(output)
    }
}
其他补充:
自定义编译生成文件路径:
  • 在protobuf闭包内添加如下配置,则生成的文件会在响应的目录,如"$projectDir/src/main"会在目录src/main/debug/java/包名/下生成
     generatedFilesBaseDir = "$projectDir/src/main"
如果要自定义多个则需要写多个proto文件,编译会生成多个相关文件。
代码如下:
syntax = "proto3";

option java_package = "edu.test.demo";
option java_multiple_files = true;

message DataPreference{
    string info = 1;
    int32 order = 2;
}
则生成的文件如下图,做了生成文件路径配置

多个proto编译生成文件

开始使用

1. 扩展定义
const val DATA_STORE_USER_FILE_NAME = "user_prefs.pb"
val Context.userDataStore : DataStore<UserPreferences> by dataStore(
    fileName = DATA_STORE_USER_FILE_NAME,
    serializer = UserPreferencesSerializer
)
2. 使用
代码如下:

            val user = userDataStore.data.first()
            Log.d(TAG.TAG, "user is ${user.name}")
            Log.d(TAG.TAG, "user is ${user.age}")
            Log.d(TAG.TAG, "user is ${user.sex}")
            Log.d(TAG.TAG, "user is ${user.tall}")
            Log.d(TAG.TAG, "user is ${user.weight}")

            //更新
            userDataStore.updateData {
                it.toBuilder().setName("张三").setAge(16).setSex(1).setWeight(65.0f).setTall(175.0f)
                    .build()
            }
            //读取
            val userUpdate = userDataStore.data.first()
            Log.d(TAG.TAG, "userUpdate is ${userUpdate.name}")
            Log.d(TAG.TAG, "userUpdate is ${userUpdate.age}")
            Log.d(TAG.TAG, "userUpdate is ${user.sex}")
            Log.d(TAG.TAG, "userUpdate is ${user.tall}")
            Log.d(TAG.TAG, "userUpdate is ${userUpdate.weight}")
日志如下:
2022-08-05 14:14:51.227 4324-4349/edu.test.demo D/Test-TAG: user is 
2022-08-05 14:14:51.227 4324-4349/edu.test.demo D/Test-TAG: user is 0
2022-08-05 14:14:51.227 4324-4349/edu.test.demo D/Test-TAG: user is 0
2022-08-05 14:14:51.227 4324-4349/edu.test.demo D/Test-TAG: user is 0.0
2022-08-05 14:14:51.227 4324-4349/edu.test.demo D/Test-TAG: user is 0.0
2022-08-05 14:14:51.258 4324-4350/edu.test.demo D/Test-TAG: userUpdate is 张三
2022-08-05 14:14:51.258 4324-4350/edu.test.demo D/Test-TAG: userUpdate is 16
2022-08-05 14:14:51.258 4324-4350/edu.test.demo D/Test-TAG: userUpdate is 0
2022-08-05 14:14:51.258 4324-4350/edu.test.demo D/Test-TAG: userUpdate is 0.0
2022-08-05 14:14:51.258 4324-4350/edu.test.demo D/Test-TAG: userUpdate is 65.0
分析:
  • 可以看出在未设置值之前,默认对象是可以读出来的,string的默认值为空,int32为0,float为0.0.
  • 在设置值之后我们读取到的就是设置的最新值。
补充:
  • 其实我们可以看到生成的datastore文件,目录是data/data/包名/files/datastore/,如下图所示:
    生成的datastore文件

使用补充,如果要使用多个自定义类型

  • 需要多个proto文件,上面已经做了说明,同时需要多个序列化生成器。
  • 会生成多个相关类,上面已经做了说明。
  • 扩展及使用方式都一样,也会生成多个存储文件,如下图所示:
    使用多个proto自定义类型生成的datastore文件

总结

  • 本篇主要对Proto DataStore的使用及注意事项做了介绍。
  • 本篇演示了Proto DataStore的简单使用过程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值