java - Protobuf C++ 与 Android Java

标签 java android c++

我正在开发一个 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 ,如下所示: 登录类:public::google::protobuf::Message { ...

而如果我尝试用 Android 生成相同的代码,这些类是从 public static final class Login extends 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 文件。如何实现?

最佳答案

经过更多的研究和大量的点击和尝试,我终于找到了解决方案。我必须做出的更改是在 Protobuf block 中的 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
        }
    }
}

这里的区别是我必须从 block 中删除 javalite 插件并保留 java 生成的代码。但是,为了使新脚本起作用,我不得不删除项目中现有的“生成”文件夹。现在我得到了 Messages.java 文件,其中包含扩展 Message 类而不是 MessageLite 类的对象,后者具有许多可用的功能,如描述符。 遗憾的是,网上没有任何地方记录这一事实。因此,如果将来有人遇到这种情况,请对您的 build.gradle 文件进行上述更改。 谢谢

关于java - Protobuf C++ 与 Android Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53606187/

相关文章:

java - 运行 WAS 7 独立客户端的要求

java - isCellEditable 和数据库不能一起工作

android - 如何在使用 InputMethodManager 隐藏后恢复软键盘

java - Android源代码如何缩小和混淆?

c++ - C++中的条件语句问题

java - 计算 Theta 更新规则的梯度输出

java - 如何将字符串拆分为二维数组并根据行访问每个分组?

android gradle 错误 : Can't register given path of type 'SOURCE' because it's out of content root

C++函数指针问题

c++ - VS2005 C++ 损坏的虚表