parent
							
								
									f410d7f697
								
							
						
					
					
						commit
						42b3b4c73c
					
				| @ -0,0 +1,227 @@ | ||||
| --- | ||||
| Gradle Plugin 入门指南 | ||||
| --- | ||||
| 
 | ||||
| #### 前言 | ||||
| 
 | ||||
| 首先,先要知道为什么需要自定义 Gradle Plugin 呢?有哪些应用场景呢? | ||||
| 
 | ||||
| 还不是因为可以结合 Transform API 做一些很神奇的事?我们可以在自定义 Plugin 中去注册我们的 Transform,以此来干预打包流程。 | ||||
| 
 | ||||
| Transform 在 Android 中都会被封装成 Task,Task 就是 Gradle 的灵魂。Android 中常见的 Task 有 ProGuard 混淆、MultiDex 重分包等等,我们写的 Transform 是会首先执行的,执行完之后再执行 Android 自带的 Transfrom。因此我们可以利用 TinyPng 在打包的时候批量压缩 res 下的所有 png 图片,甚至可以修改字节码,把项目中的 new Thread 全部替换成 CustomThread 等,Transform API 还是很强大的,本节先讲如何去自定义一个 Gradle Plugin,下一篇会仔细讲 Transform API 的玩法。 | ||||
| 
 | ||||
| 笔者刚开始写 Gradle Plugin 的时候,估计和大家一样,网上搜一些文章然后去实践,然鹅各种奇怪问题,自定义 Plugin 本身代码并不多,容易出错的就是配置上的问题,这种问题很难发现,所以本文就是来为大家填坑。 | ||||
| 
 | ||||
| #### 热身 | ||||
| 
 | ||||
| 自定义 Gradle Plugin 有三种办法: | ||||
| 
 | ||||
| 1. 直接在 build.gradle 文件中写 | ||||
| 2. 新建 buildSrc 工程 | ||||
| 3. 新建 Java Library 工程 | ||||
| 
 | ||||
| 首先,我们尝试第一种方式去写,每个 Gradle 工程都会有一个 build.gradle 文件,这个文件配置了工程所需的各种配置信息,它是一个 Groovy 文件,所以我们可以直接在文件里面写: | ||||
| 
 | ||||
| ```java | ||||
| class MyPlugin implements Plugin<Project>{ | ||||
|     @Override | ||||
|     void apply(Project target) { | ||||
|         target.task("hello"){ | ||||
|             println('Hello Plguin~') | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| apply plugin: MyPlugin | ||||
| ``` | ||||
| 
 | ||||
| 在 Plugin 中我们定义了一个 hello 的 Task,然后 apply 这个 Plugin,现在我们可以打开 Terminal 执行这个 Task: | ||||
| 
 | ||||
| ``` | ||||
| ./gradlew task -q hello | ||||
| ``` | ||||
| 
 | ||||
| 就输出 Hello Plugin~ 啦。这里 -q 参数表示静默执行,后面就是我们定义的 Task name,还是很简单的。 | ||||
| 
 | ||||
| 如果这个你还有问题,就不用往下看了 :) | ||||
| 
 | ||||
| 第二种 buildSrc 方式,也是官方文档中的方式,但是这种方式定义的 Plugin 只能在当前工程使用,如果我想把这个 Plugin 发布出去就不行了,所以我们直接鄙弃这种方式。 | ||||
| 
 | ||||
| 第三种扩展性就很强了,所以本文就使用新建 Java Library 方式去自定义 Plugin。 | ||||
| 
 | ||||
| #### 正文 | ||||
| 
 | ||||
| 首先新建一个 Java Library 的工程,名叫 "my_plugin",然后在 my_plugin 工程的 build.gradle 添加一些依赖: | ||||
| 
 | ||||
| ```java | ||||
| apply plugin: 'java-library' | ||||
| apply plugin: 'groovy' | ||||
| apply plugin: 'maven' | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation fileTree(dir: 'libs', include: ['*.jar']) | ||||
| 
 | ||||
|     //Gradle Plugin 依赖 | ||||
|     implementation gradleApi() | ||||
|     //本地发布 Plugin | ||||
|     implementation localGroovy() | ||||
| } | ||||
| 
 | ||||
| sourceCompatibility = "7" | ||||
| targetCompatibility = "7" | ||||
| ``` | ||||
| 
 | ||||
| 这时候其实我们只有一个 Java 包,所以需要新建一个对应的 groovy 包,如下: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| MyPlugin 中即是我们的自定义的 Plugin,新建 MyPlugin 文件的时候一定是 Groovy 文件,**注意要有 .groovy 后缀**,代码如下: | ||||
| 
 | ||||
| ```java | ||||
| package top.omooo.my_plugin | ||||
| 
 | ||||
| import org.gradle.api.Plugin | ||||
| import org.gradle.api.Project | ||||
| 
 | ||||
| class MyPlugin implements Plugin<Project> { | ||||
|     @Override | ||||
|     void apply(Project project) { | ||||
|         project.task('myPlugin'){ | ||||
|             println('MyPlugin Start ~') | ||||
|         } | ||||
|     } | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| 代码还是一如既往的简单~ | ||||
| 
 | ||||
| 图中有几个点需要解释一下: | ||||
| 
 | ||||
| 1. 我新建了一个 resources 文件夹 | ||||
| 
 | ||||
|    这里是用来注册我们自定义的 Plugin,需要注意是,该目录下的**文件夹命名**一定不能错,笔者最开始就是因为把 META-INF 错写成了 META_INF,折腾了好久才发现。 | ||||
| 
 | ||||
| 2. top.omooo.my_plugin.properties | ||||
| 
 | ||||
|    这个文件的内容就是我们的自定义 Plugin,按图上写就行了。不过需要注意的是,文件名为 top.omooo.my_plugin,文件名是可以随意定义的,但是最好能是包名,这就是我们的 Plugin 的 Id,回顾上面,我们依赖了 apply plugin:  'groovy',这里的 groovy 就是 Plugin Id,所以当我们在外部模块依赖我们的自定义 Plugin 的时候就是: | ||||
| 
 | ||||
|    ```java | ||||
|    apply plugin: 'top.omooo.my_plugin' | ||||
|    ``` | ||||
| 
 | ||||
| 但是这时候我们的 Plugin 还不能被 app 模块依赖,因为还没发布呢,那该如何发布呢? | ||||
| 
 | ||||
| 我们可以选择发布到 maven 仓库,也可以在本地发布,不过在发布之前,都要做一件事,那就是指定 Plugin 的标示信息: | ||||
| 
 | ||||
| ```java | ||||
| apply plugin: 'java-library' | ||||
| apply plugin: 'groovy' | ||||
| apply plugin: 'maven' | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation fileTree(dir: 'libs', include: ['*.jar']) | ||||
| 
 | ||||
|     //Gradle Plugin 依赖 | ||||
|     implementation gradleApi() | ||||
|     //本地发布 Plugin | ||||
|     implementation localGroovy() | ||||
| } | ||||
| 
 | ||||
| //Plugin 标示信息 | ||||
| group 'top.omooo.my_plugin' | ||||
| version '1.0' | ||||
| 
 | ||||
| //本地发布,发布到根目录的 /repo 文件夹下 | ||||
| uploadArchives{ | ||||
|     repositories { | ||||
|         mavenDeployer{ | ||||
|             repository(url :uri('../repo')) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sourceCompatibility = "7" | ||||
| targetCompatibility = "7" | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
| 我们引入一个依赖,其实是有三部分组成的: | ||||
| 
 | ||||
| ```java | ||||
| compile 'com.android.tools.build:gradle:3.3.2' | ||||
| //groupId: com.android.tools.build | ||||
| //artifactId: gradle | ||||
| //version: 3.3.2 | ||||
| ``` | ||||
| 
 | ||||
| 但是你可能会问,这里我们为什么没有写 artifactId,因为 artifactId 默认为工程名字,所以我们可以不写,所以如果我们在引入我们的 Plugin 的时候,就需要这样写了: | ||||
| 
 | ||||
| ```java | ||||
| top.omooo.my_plugin:my_plugin:1.0 | ||||
| ``` | ||||
| 
 | ||||
| 这时候我们我们还没有真正的发布,需要执行: | ||||
| 
 | ||||
| ```java | ||||
| ./gradlew task uploadArchives | ||||
| ``` | ||||
| 
 | ||||
| 执行完后,就可以看到我们根目录生成了一个 repo 文件夹,里面就是我们的插件 jar 包了: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 本地有了 Plugin,我们就可以在主工程即 Project 的 build.gradle 引入了: | ||||
| 
 | ||||
| ```java | ||||
| buildscript { | ||||
|     repositories { | ||||
|         google() | ||||
|         jcenter() | ||||
|         maven{ | ||||
|             //本地 Plugin 地址,注意只有一个 . | ||||
|             url uri('./repo') | ||||
|         } | ||||
|     } | ||||
|     dependencies { | ||||
|         classpath 'com.android.tools.build:gradle:3.3.2' | ||||
|         //自定义的 Plugin | ||||
|         classpath 'top.omooo.my_plugin:my_plugin:1.0' | ||||
|         // NOTE: Do not place your application dependencies here; they belong | ||||
|         // in the individual module build.gradle files | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| allprojects { | ||||
|     repositories { | ||||
|         maven{ | ||||
|             url uri('./repo') | ||||
|         } | ||||
|         google() | ||||
|         jcenter() | ||||
|          | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| task clean(type: Delete) { | ||||
|     delete rootProject.buildDir | ||||
| } | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
| 这是我们就可以在我们依赖的包中看到那个熟悉的身影了,这时候一定要**检查看看我们写的类是不是打入了 jar 包**: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 完成之后,我们就可以在工程下的所有模块依赖这个 Plugin,比如我们可以在 app module 下依赖这个模块: | ||||
| 
 | ||||
| ```java | ||||
| apply plugin: 'top.omooo.my_plugin' | ||||
| ``` | ||||
| 
 | ||||
| 之后,我们肯定会改 MyPlugin 里面的代码的,这时候就要重新上传依赖,用的还是那个命令: | ||||
| 
 | ||||
| ```java | ||||
| ./gradlew task uploadArchives | ||||
| ``` | ||||
| 
 | ||||
| OK,大功告成~ | ||||
| After Width: | Height: | Size: 148 KiB | 
| After Width: | Height: | Size: 97 KiB | 
| After Width: | Height: | Size: 78 KiB | 
					Loading…
					
					
				
		Reference in new issue