Protobuf | 安装 Gradle 插件编译 proto 文件

Protobuf | 安装 Gradle 插件编译 proto 文件

  • 如果评论区没有及时回复,欢迎来公众号:ByteCode 咨询
  • 公众号:ByteCode。致力于分享最新技术原创文章,涉及 Kotlin、Jetpack、算法、译文、系统源码相关的文章

相关系列:

前言

Google 除了提供命令行的方式编译 proto 文件,还提供了 AndroidStudio 插件 protobuf-gradle-plugin 来编译 proto 文件。

如何在项目中添加 Gradle 插件

在项目中添加 Gradle 插件编译 proto 文件,非常简单,我先给出全部配置,文件内容比较长,稍后会逐个分析,将下列内容添加在 protobuf 文件所在的 module 的 build.gradle 文件内

/**
* plugins 和 apply plugin 的区别:
* plugins 是一种比较新的方法,它所引用的插件必须在 Gradle plugin repository 的仓库可见的
* apply plugin 是一种比较老的方式,在 Android4.1 的时候,创建项目的时候,已经将 apply plugin 方法替换为 plugins
*
*/

plugins {
id 'com.android.library'
id "com.google.protobuf" version "0.8.12"
}

// 或者使用下面的方式,但是不建议使用
//apply plugin: 'com.android.library'
//apply plugin: "com.google.protobuf"

android {
compileSdkVersion 30

// 设置 proto 文件位置
sourceSets {
main {
proto {
// proto 文件默认路径是 src/main/proto
// 可以通过 srcDir 修改 proto 文件的位置
srcDir 'src/main/proto'
}
}
}
}


/**
* 注意配置 protoc 命令,分为不同的版本,版本不同配置的方式不同,
* 网上大部分都是 3.0.x ~ 3.7.x 的配置方式,关于这种配置方法,可以查看 [protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) 文档,这里不在演示了,也不建议使用
* 在此项目中使用的是 3.8 以后 的配置的配置,
*/
protobuf {
// 设置 protoc 的版本
protoc {
// //从仓库下载 protoc 这里的版本号需要与依赖 com.google.protobuf:protobuf-javalite:xxx 版本相同
artifact = 'com.google.protobuf:protoc:3.10.0'
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option "lite"
}
}
}
}

// 默认生成目录 $buildDir/generated/source/proto 通过 generatedFilesBaseDir 改变生成位置
generatedFilesBaseDir = "$projectDir/src/main"
}

// 添加 protobuf 需要的依赖,这里是用的是 javalite 版本
dependencies {
implementation "com.google.protobuf:protobuf-javalite:3.10.0"
}

只需要将上面的内容添加在 protobuf 文件所在的 module 的 build.gradle 文件内,就可以开始编译 proto 文件,proto 文件默认存放路径 src/main/proto,需要在该目录下新建 proto 文件。

新建 Person.proto 文件,添加以下内容

syntax = "proto3";

option java_package = "com.hi.dhl.datastore.protobuf";
option java_outer_classname = "PersonProtos";

message Person {
// 格式:字段类型 + 字段名称 + 字段编号
string name = 1;
}

之后点击 Build -> Rebuild Project,即可生成对应的 Java 文件,默认生成目录 $buildDir/generated/source/proto

接下里我们来分析如何在项目中添加 Gradle 插件编译 proto 文件,别看文件内容很长,总共拆分下来只需要三步。

步骤一:添加 Protobuf 插件

AndroidStudio 提供了两种方式 plugins{...}apply plugin,来添加 Protobuf 插件

  • 使用 apply plugin 方法
apply plugin: "com.google.protobuf"
  • 使用 plugins{...} 方法,
plugins {
id "com.google.protobuf" version "0.8.12"
}

建议使用 plugins{...} 方式,在 AndroidStudio 4.1 以上,创建项目的时候,已经将 apply plugin 方法替换为 plugins{...}

步骤二:配置 protoc 命令

注意: protoc 命令,分为不同的版本,版本不同配置的方式不同,网上大部分都是 3.0.x ~ 3.7.x 的配置方式,关于这种配置方法,可以查看 protobuf-gradle-plugin 文档,这里不在演示了,也不建议使用。

我们直接来看看 protoc >= 3.8 之后的方法,添加下面内容到 protobuf 文件所在的 module 的 build.gradle 文件内。

protobuf {
// 设置 protoc 的版本
protoc {
// //从仓库下载 protoc 这里的版本号需要与依赖 com.google.protobuf:protobuf-javalite:xxx 版本相同
artifact = 'com.google.protobuf:protoc:3.10.0'
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option "lite"
}
}
}
}
}

通过 artifact 指定的 protoc 的版本号,需要与 添加 protobuf 需要的依赖 的版本相同。

默认生成目录 $buildDir/generated/source/proto 可以通过 generatedFilesBaseDir 改变生成位置。

protobuf {
......

// 默认生成目录 $buildDir/generated/source/proto 通过 generatedFilesBaseDir 改变生成位置
generatedFilesBaseDir = "$projectDir/src/main"
}

步骤三:添加 protobuf 需要的依赖

// 这里是用的是 javalite 版本
dependencies {
implementation "com.google.protobuf:protobuf-javalite:3.10.0"
}

只需要完成前面三步,就可以开始编译 proto 文件,每次 proto 文件内容变更的时候,只要重新点击 Build -> Rebuild Project,即可生成对应的 Java 文件。

proto 文件默认存放路径是 src/main/proto, 可以添加下面配置更改 proto 文件存放的位置。

android {
// 设置 proto 文件位置
sourceSets {
main {
proto {
// proto 文件默认路径是 src/main/proto
// 可以通过 srcDir 修改 proto 文件的位置
srcDir 'src/main/proto'
}
}
}
}

常见问题

错误一:编译没有报错,为什么没有生成对应的目标文件?

如果没有更改 proto 文件存储路径,默认存放路径是 src/main/proto,请检查你的 proto 文件存放位置是否正确

总结

安装 Gradle 插件编译 proto 文件,相比于 ubuntu 和 MAC 安装方式,要复杂点,但是用起来是相当方便的,如果在使用过程中遇到了任何问题,欢迎在评论区留言,一起来完善这份教程,如果没有及时回复,可以来公众号:ByteCode 找我咨询。

致力于分享一系列 Android 系统源码、逆向分析、算法、翻译、Jetpack 源码相关的文章,在技术的道路上一起前进

Android10 源码分析

正在写一系列的 Android 10 源码分析的文章,了解系统源码,不仅有助于分析问题,在面试过程中,对我们也是非常有帮助的,如果你同我一样喜欢研究 Android 源码,可以关注我 GitHub 上的 Android10-Source-Analysis

算法题库的归纳和总结

由于 LeetCode 的题库庞大,每个分类都能筛选出数百道题,由于每个人的精力有限,不可能刷完所有题目,因此我按照经典类型题目去分类、和题目的难易程度去排序。

  • 数据结构: 数组、栈、队列、字符串、链表、树……
  • 算法: 查找算法、搜索算法、位运算、排序、数学、……

每道题目都会用 Java 和 kotlin 去实现,并且每道题目都有解题思路,如果你同我一样喜欢算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:Leetcode-Solutions-with-Java-And-Kotlin

精选国外的技术文章

目前正在整理和翻译一系列精选国外的技术文章,不仅仅是翻译,很多优秀的英文技术文章提供了很好思路和方法,每篇文章都会有译者思考部分,对原文的更加深入的解读,可以关注我 GitHub 上的 Technical-Article-Translation

评论