(七)Android Gradle - 三种自定义插件方式
一、前言
我们知道,在Android中每一次的编译和打包其实都是一个个task任务顺序执行或者并发执行最终生成一个Apk。也就是说所有的任务可以想象成一条线,上个任务的产出就是下一个任务的输入(流水线作业😄)。例如下图:一个简单的APK构建流程
例如下图:实际构建中的task任务
可以简单的理解为:
- 前缀带有compile的task:一般是做编译转换的任务,例如:Java文件转换成Class
- 前缀带有merge的task:一般是合并各种资源文件任务,例如:所有的Assets文件合成一个
- 前缀带有package的task:一般是将资源文件进行打包压缩
- 前缀带有assemble的task:将打包的文件组合一起形成一个Apk。(一般来说只会有一个)
具体Task分析可以查看源码,如下:
Android Gradle Plugin7.1.2源码下载
依赖进项目即可查看对应的Task,例如ProcessDebugJavaResTask:
提示:ProcessDebugJavaResTask其实就是ProcessJavaResTask,中间的Debug根据你项目中配置的productFlavors(如果没有配置,默认debug/release)来决定,其他task也是如此。
二、我们可以做什么?
知道每一个task的作用后,我们找到我们需要的task,在其执行前或者执行后插入我们自定义的插件(可以理解成一个也是task),例如:
- 在class生成后,Dex文件生成前,插入我们自定义的代码(包括对第三方SDK)
- 对AndroidManifest.xml进行插入代码
- 对资源图片(PNG)压缩
而上面这些操作的基础,都是需要把自己的插件依赖进项目里,然后对相关的task进行hook。
例如下图(引入我们最常用的Kotlin插件):
apply plugin: 'kotlin-android-extensions'apply plugin: 'kotlin-kapt'
接下来, 我们将介绍如何创建自己的插件并通过apply plugin方式依赖进项目。
三、创建插件并依赖进项目
提示:以下配置都基于AGP版本:7.1.2 Gradle版本:7.2
首先,创建插件方式有三种,如下:
1.直接在build.gradle中创建
2.在buildSrc文件夹中创建
3.创建一个Module或者Library的方式创建
接下来,我们分别介绍下三种方式如何使用
3.1 build.gradle中自定义插件
这种方式比较简单,就不过多介绍,直接在App模块的build.gradle中创建,代码如下:
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android'}class CustomPlugin implements Plugin{ @Override void apply(Project target) { printf "hello,this is CustomPlugin" }}apply plugin: CustomPlugin
提示:自定义插件都需要实现Plugin接口。
运行,同步下,结果如下:
3.2 在buildSrc文件中自定义插件
这里需要分别介绍Java和Kotlin的创建,发现还是有一些不一样的。推荐用Kotlin开发,Google主推
3.3.1 使用Java语言
首先,在项目的根目录下创建一个buildSrc文件夹,然后在buildSrc文件夹里创建一个build.gradle文件,build.gradle文件代码如下:
apply plugin: "java"apply plugin: 'java-gradle-plugin'
提示:如果需要支持Groovy,自行添加 apply plugin: 'groovy'
目录结构截图如下:
然后,点击Sync同步项目,就会发现buildSrc文件夹下会多出一些gradle的相关文件,截图如下:
如果你的Gradle版本7.2可以发现,在settings.gradle多了一个buildSrc文件夹,这是因为buildSrc是系统默认的文件夹。
接下来在buildSrc上右键新建文件夹,会发现多出一些文件夹选择,如下:
选择Java文件夹,在其下面创建一个MyPlugin.java文件, 截图如下:
代码如下:
class MyPlugin implements Plugin { @Override public void apply(Project target) { System.out.println("hello,this is CustomPlugin"); }}
还是一样在App模块的build.gradle中加入如下代码:
apply plugin: MyPlugin
运行,同步下,结果如下:
3.3.1 使用Kotlin语言
主要流程与上面Java的创建一样,不同的是build.gradle文件的创建和Kotlin文件夹,如下:
需要注意点:
- build.gradle为build.gradle.ktx
- 文件夹为kotlin
build.gradle.ktx代码如下:
plugins { `kotlin-dsl`}repositories { mavenCentral()}
如果你的Gradle版本为7.0以上,可能会遇到如下问题:Build was configured to prefer settings repositories over project repositories but repository 'Gradle Libs' was added by unknown code
只需要如下修改即可:
在setting.gradle中,将
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
修改为:
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
截图如下:
问题的原因就是Gradle希望开发者将所有仓库配置都在这里设置,而不是根据每个项目自己去导入。
3.3 通过Module/Library自定义插件
第一步:新建一个Module或者Library
因为无论选择哪个最后只保留src文件夹和build.gradle,文件其他全部删除。将上面的MyPlugin.java放到包里,截图如下:
第二步:创建com.example.plugins.properties文件
路径如下:resources/META-INF/gradle-plugins/com.example.plugins.properties
注意:跟java文件夹是在同一层,resources/META-INF/gradle-plugins/必须是这个路径,后面的文件名可以自定义,后面会用到。
文件内容如下:
#配置插件的入口类(必须保证文件路径正确)implementation-class=com.example.customplugin.MyPlugin2
第三步:发布代码到本地
修改build.gradle代码如下(代码中包含Gradle7.0以上和以下两种方案):
apply plugin: "java"apply plugin: 'java-gradle-plugin'repositories { google() mavenCentral()}//Gralde 7.0以上选择下面发布到本地apply plugin: 'maven-publish'publishing { publications{ maven(MavenPublication) { groupId "com.example.custom" artifactId 'CustomPlugin' version "1.0.0" //如果是war包填写components.web,如果是jar包填写components.java from components.java } } repositories { maven { url = "../plugins" } }}//Gralde 7.0以下选择下面发布到本地//打包到本地或者远程maven库//apply plugin: 'maven'//uploadArchives {// repositories {// mavenDeployer {// //这个就是配置这个自定义插件的classpath// //例如根项目依赖:classpath "com.example.custom:CustomPlugin:1.0.0"// pom.groupId = 'com.example.custom'// pom.artifactId = 'CustomPlugin'// pom.version = '1.0.0'// //提交到远程服务器// // repository(url:"服务器地址"){// // authentication(userName:'admin',password:'123456')// // }// //提交本地maven地址:../plugins// repository(url: uri('../plugins'))// }// }//}
第四步,点击task发布
可以看到在项目中多了个plugins文件夹,如下:
第五步:引入插件到工程
在根build.gradle中加入下面代码
buildscript { dependencies { classpath "com.example.custom:CustomPlugin:1.0.0" }}
第六步:添加依赖
把com.example.plugins添加依赖,这里名字也就是我们上面创建com.example.plugins.properties文件
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'com.example.plugins'}
第七步:运行代码
四、总结
如果是为了快速测试可以选择在直接在build.gradle中创建
如果只有一个插件开发,选择在buildSrc文件夹中创建
如果有多个插件开发,选择以创建一个Module或者Library的方式创建
建议:如果是在项目中,使用第三种方式。在语言上,使用Kotlin进行插件开发。
项目地址