我正在开发一个Android项目,其中我们使用Google的Protobuf库进行序列化/反序列化。过去,我曾使用C ++开发Protobuf。假设我有一个带有一个protobuf对象的.proto文件:
message LoginAck {
enum LoginResult {
OK = 1;
NO_AUTH = 2;
ERROR = 3;
}
optional LoginResult result = 1;
}
在用C ++生成代码时,为此对象生成的类是从google :: protobuf :: Message派生的,如下所示: 类登录:公共:: google :: protobuf ::消息{ ... }
如果我尝试使用Android生成相同的代码,则这些类是从以下类派生/扩展的 公共静态最终课程Login扩展了com.google.protobuf.GeneratedMessageLite
com.google.protobuf.GeneratedMessageLite<
Login, Login.Builder> implements
// @@protoc_insertion_point(message_implements:Login)
LoginOrBuilder {
...
}
问题在于,对于MessageLite类型,我无法使用只能通过Message类访问的描述符。我的Gradle构建文件如下所示:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.google.protobuf:protobuf-java:3.4.0'
implementation 'com.koushikdutta.async:androidasync:2.1.6'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
protobuf {
generatedFilesBaseDir = "$projectDir/src/generated"
protoc {
// You still need protoc like in the non-Android case
artifact = 'com.google.protobuf:protoc:3.4.0'
}
plugins {
javalite {
// The codegen for lite comes as a separate artifact
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
// In most cases, you don't need the full Java output
// if you use the lite output.
remove java
}
task.plugins {
javalite {}
}
task.generateDescriptorSet = true
task.descriptorSetOptions.includeSourceInfo = true
task.descriptorSetOptions.includeImports = true
}
}
}
我想使用从Message扩展而不是MessageLite扩展的类生成Java文件。如何实现呢?
答案 0 :(得分:0)
经过更多研究和大量尝试之后,我终于找到了解决方案。我必须进行的更改位于Protobuf块中的build.gradle文件中,如下所示:
protobuf {
generatedFilesBaseDir = "$projectDir/src/generated"
protoc {
// You still need protoc like in the non-Android case
artifact = 'com.google.protobuf:protoc:3.4.0'
}
generateProtoTasks {
all().each { task ->
task.builtins {
// In most cases you don't need the full Java output
// if you use the lite output.
java {}
}
task.generateDescriptorSet = true
task.descriptorSetOptions.includeSourceInfo = true
task.descriptorSetOptions.includeImports = true
}
}
}
这里的区别是我必须从块中删除javalite插件并保留Java生成的代码。但是,为了使新脚本起作用,我不得不删除项目中现有的“生成”文件夹。现在,我得到了Messages.java文件,该对象具有扩展Message类而不是MessageLite类的对象,该类具有很多可用的功能,例如描述符。 可惜的是,这个事实没有在线记录在任何地方。因此,如果将来有人遇到这种情况,请对build.gradle文件进行上述更改。 谢谢