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

被折叠的 条评论
为什么被折叠?



