使用 Proto DataStore KTS新写法

Gradle插件与protobuf集成:生成与使用示例
文章讲述了在Android项目中如何使用Gradle插件与protobuf进行集成,包括添加依赖、自定义编译选项、生成Java代码以及实际应用中的Repository接口和DataStore操作。

插件

plugins {
    id("com.android.application")
//    id("org.jetbrains.kotlin.android")
    id("kotlin-android")
    id("kotlin-kapt")
    id("androidx.navigation.safeargs.kotlin")
    id("com.google.protobuf") version ("0.9.4")
}

依赖

  implementation 'androidx.datastore:datastore:1.0.0'
  implementation 'com.google.protobuf:protobuf-javalite:3.21.6'

生成任务
之前的写法识别不了,找了好多地方,都没有完整的写法,真是坑。

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

    // 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'
//
//                }
//            }
//        }
//    }
    generateProtoTasks {
        all().forEach { task ->
            task.builtins{
                create("java") {
                    option("lite")
                }
            }
        }
    }

}

然后再 app/main/proto 目录下加入 proto文件,重新 rebuild项目
例如

syntax = "proto3";

option java_package = "com.xxx.classcard.data.model";
option java_multiple_files = true;

message UserPreferences {
  // filter for showing / hiding completed tasks
  bool show_completed = 1;
}

生成的代码就在
app\build\generated\source\proto\sampleDebug\java\com\xxxx\classcard\data\model

如下

/**
 * Protobuf type {@code UserPreferences}
 */
public  final class UserPreferences extends
    com.google.protobuf.GeneratedMessageLite<
        UserPreferences, UserPreferences.Builder> implements
    // @@protoc_insertion_point(message_implements:UserPreferences)
    UserPreferencesOrBuilder {
  private UserPreferences() {
  }
  public static final int SHOW_COMPLETED_FIELD_NUMBER = 1;
  private boolean showCompleted_;
  /**
   * <pre>
   * filter for showing / hiding completed tasks
   * </pre>
   *
   * <code>bool show_completed = 1;</code>
   * @return The showCompleted.
   */
  @java.lang.Override
  public boolean getShowCompleted() {
    return showCompleted_;
  }
  /**
   * <pre>
   * filter for showing / hiding completed tasks
   * </pre>
   *
   * <code>bool show_completed = 1;</code>
   * @param value The showCompleted to set.
   */
  private void setShowCompleted(boolean value) {
    
    showCompleted_ = value;
  }

具体使用的话
repo

interface IDataStoreRepository {
    suspend fun saveData(key: Preferences.Key<String>, value: String)

    fun readData(key: Preferences.Key<String>,defaultValue:String): Flow<String>


    fun readClassInfo():Flow<ClassInfoLocal>

    suspend fun saveClassInfo(classInfoLocal: ClassInfoLocal)

}

object PreferencesKeys {
    // SharedPreferences 的测试的 key
    val KEY_PREFERENCE = "ClassCardPre"
    val KEY_CLASSINFO= "ClassCardClass"

    // DataStore 的测试的 key
    val KEY_ORGANIZATION_NAME = preferencesKey<String>("OrganizationName")
    val KEY_ORGANIZATION_LOGO = preferencesKey<String>("OrganizationLogo")
}

具体实现

class DataStoreRepository(val context: Context) : IDataStoreRepository {

    var dataStorePref: DataStore<Preferences> = context.createDataStore(
        name = PreferencesKeys.KEY_PREFERENCE
    )

    var dataStoreProto: DataStore<ClassInfoLocal> = context.createDataStore(
        KEY_CLASSINFO, ClassInfoLocalSerializer
    )


    override suspend fun saveData(key: Preferences.Key<String>, value: String) {
        dataStorePref.edit { mutablePreferences ->
            Log.i("linlian", "DataStore saveData ${key.name},value=$value")
            mutablePreferences[key] = value
        }
    }

    override fun readData(key: Preferences.Key<String>, defaultValue: String): Flow<String> =
        dataStorePref.data
            .catch {
                // 当读取数据遇到错误时,如果是 `IOException` 异常,发送一个 emptyPreferences,来重新使用
                // 但是如果是其他的异常,最好将它抛出去,不要隐藏问题
                if (it is IOException) {
                    it.printStackTrace()
                    emit(emptyPreferences())
                } else {
                    throw it
                }
            }.map { preferences ->

               val value =  preferences[key] ?: defaultValue
                Log.i("linlian", "DataStore read ${key.name},value=$value")
                value
            }

    override fun readClassInfo(): Flow<ClassInfoLocal> {
        return dataStoreProto.data
            .catch {
                if (it is IOException) {
                    it.printStackTrace()
                    emit(ClassInfoLocal.getDefaultInstance())
                } else {
                    throw it
                }
            }
    }

    override suspend fun saveClassInfo(classInfoLocal: ClassInfoLocal) {
        dataStoreProto.updateData { preValue ->
            preValue.toBuilder()
                .setClassName(classInfoLocal.className)
                .setImage(classInfoLocal.image)
                .setLabel(classInfoLocal.label)
                .setHeaderTeacher(classInfoLocal.headerTeacher)
                .setClassStudentCount(classInfoLocal.classStudentCount)
                .build()

        }
    }
}

viewmodle层

private val dataStoreRepository: IDataStoreRepository = DataStoreRepository(context)

    /**
     * 主体机构信息
     */
    val organizationFlow = combine(
        dataStoreRepository.readData(PreferencesKeys.KEY_ORGANIZATION_NAME, ""),
        dataStoreRepository.readData(PreferencesKeys.KEY_ORGANIZATION_LOGO, "")
    ) { name, logo ->
        OrganizationInfo(name, logo)
    }


   

    /**
     * 班级基础信息
     */
    val classInfoFlow = dataStoreRepository.readClassInfo()

UI层使用

val orgInfo = homeViewModel.organizationFlow.collectAsState(null)

Text(
                text = "${orgInfo.value?.name}",
                style = if (isWiderScreen) MaterialTheme.typography.headlineMedium else MaterialTheme.typography.titleMedium,
                textAlign = TextAlign.Center,
            )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值