Protobuf JavaLite是否支持google.protobuf.Struct?及相关技术咨询
我们尝试使用的Proto消息定义:
message Cta { string title = 1; string pid = 2; google.protobuf.Struct params = 3; }
技术疑问与解答
问题1:安卓平台推荐的protobuf-lite库是否支持google.protobuf.Struct?
Protobuf JavaLite 不支持google.protobuf.Struct这类动态消息类型。JavaLite是针对移动端优化的轻量版本,砍掉了反射、动态消息等重量级特性,Struct、Value、ListValue这类动态类型不在其支持范围内。问题2:在哪里可以查询到Protobuf Javalite运行时所支持的已知Proto类型列表?
可以直接查看protobuf-javalite的源码或官方发布的jar包内容。JavaLite支持的类型包括:基础标量类型(string、int32、bool等)、自定义消息类型、枚举,以及基础容器类型(如repeated字段)。另外,官方文档会明确标注JavaLite不支持的特性,反向推导也能得到支持的类型范围。问题3:若Struct/Value不被JavaLite支持,那么对应HashMap<String, Object>的推荐Proto类型是什么?
有两种常用替代方案:自定义键值对消息(类型安全)
定义包含键和多类型值的消息,用repeated字段模拟Map:message KeyValuePair { string key = 1; oneof value { string string_val = 2; int32 int_val = 3; bool bool_val = 4; // 根据业务需求添加需要支持的其他类型 } } message Cta { string title = 1; string pid = 2; repeated KeyValuePair params = 3; }适合业务明确、值类型有限的场景,能保留Proto的类型校验能力。
JSON字符串存储(高灵活性)
将参数序列化为JSON字符串,用string字段存储:message Cta { string title = 1; string pid = 2; string params_json = 3; }灵活性高,但失去了Proto的类型校验,需要自行处理JSON的序列化与反序列化。
我们使用的Gradle配置:
plugins { id 'com.android.library' id 'kotlin-android' id 'com.google.protobuf' id 'org.jetbrains.kotlin.android' } java { sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 } android { compileSdkVersion 33 buildToolsVersion "30.0.3" namespace 'com.boom.protobuf' } protobuf { protoc { artifact = "com.google.protobuf:protoc:3.20.1" } generateProtoTasks { all().each { task -> task.builtins { java { option 'lite' } kotlin { option 'lite' } } } } } dependencies { api 'com.google.protobuf:protobuf-kotlin-lite:3.23.0' api 'com.google.protobuf:protobuf-javalite:3.23.0' }
内容的提问来源于stack exchange,提问作者Sudev Ambadi

