自定义 Gradle 插件
- 首先新建一个项目
- 新建一个module模块,删除无关文件,只需保留main和build.gradle文件即可
- gradle文件中删除之前默认所有配置,引入如下配置
//管理仓库的插件
apply plugin: 'maven'
//groovy插件
apply plugin:'groovy'
dependencies {
compile gradleApi()
compile localGroovy()
}
- 在main目录下新建groovy和main文件夹
- 在groovy文件夹下建包,写对应的插件
package com.okay.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
public class LifeCyclePlugin implements Plugin<Project>{
@Override
void apply(Project project) {
System.out.println("== LifeCyclePlugin Plugin gradle plugin ==")
}
}
- 在gradle中配置插件版本和仓库信息
group = 'com.okay.plugin'
version = '1.0.0'
uploadArchives{
repositories{
mavenDeployer{
//本地maven地址
repository(url : uri('../asm_lifecycle_repo'))
}
}
}
7.在plugin/src/main目录下新建目录resources/META-INF/gradle-plguins,然后在此目录下新建一个文件zyl.asm.lifecycle.properties。(zyl.asm.lifecycle是插件名称)
implementation-class= com.okay.plugin.LifeCyclePlugin
8.生成插件
现在可以在 Android Studio 的右边栏找到 Gradle 中Tasks/upload下找到并点击 uploadArchives,执行 plugin 的部署任务。就会生成asm_lifecycle_repo文件夹
测试插件
- 在app的build.gradle文件中添加插件配置
apply plugin: 'com.android.application'
apply plugin: 'zyl.asm.lifecycle'
buildscript {
repositories {
//自定义插件的maven地址
maven {url '../asm_lifecycle_repo'}
}
dependencies {
//加载自定义插件 group+module+version
classpath 'com.okay.plugin:asm_lifecycle_pulgin:1.0.0'
}
}
2.在studio的Terminal控制台输入./gradlew clean assembledebug命令,控制台输出
> Configure project :app
== LifeCyclePlugin Plugin gradle plugin ==
BUILD SUCCESSFUL in 22s
打印了我们的日志,说明插件生效了。
自定义Transform,实现遍历.class文件
- 在gradle插件的基础上,添加依赖
apply plugin: 'maven'
apply plugin:'groovy'
dependencies {
compile gradleApi()
compile localGroovy()
//添加gradle库
compile 'com.android.tools.build:gradle:3.6.2'
}
...
- 在grovvy文件夹下新建新建LifeCycleTransform.groovy,并继承 Transform 抽象类。
package com.okay.plugin
import com.android.build.api.transform.DirectoryInput
import com.android.build.api.transform.QualifiedContent
import com.android.build.api.transform.Transform
import com.android.build.api.transform.TransformException
import com.android.build.api.transform.TransformInvocation
import com.android.build.gradle.internal.pipeline.TransformManager
import groovy.io.FileType
public class LifeCycleTransform extends Transform{
/**
* 设置我们自定义的Transform对应的Task名称。Gradle在编译的时候,会将这个名称显示在控制台上。
* 比如:Task:app:transformClassesWithXXXForDe...
*/
@Override
String getName() {
return "ZylTransform"
}
/**
* 在项目中会有各种各样格式的文件,通过getInputType可以设置LifeCycleTransform接收的文件类型,
* 此方法返回的类型是 Set<QualifiedContent.ContentType> 集合
*
*/
@Override
Set<QualifiedContent.ContentType> getInputTypes() {
return TransformManager.CONTENT_CLASS
}
/**
* 这个方法规定自定义 Transform 检索的范围
*/
@Override
Set<? super QualifiedContent.Scope> getScopes() {
return TransformManager.PROJECT_ONLY
}
/**
* 表示当前 Transform 是否支持增量编译,我们不需要增量编译,所以直接返回 false 即可。
*
*/
@Override
boolean isIncremental() {
return false
}
/**
*
* @param transformInvocation
* @throws TransformException
* @throws InterruptedException
* @throws IOException
*/
@Override
void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
super.transform(transformInvocation)
//拿到所有的class文件
def inputs = transformInvocation.inputs
inputs.each { transformInput->
transformInput.directoryInputs.each { DirectoryInput directoryInput->
File dir = directoryInput.file
if (dir){
dir.traverse(type: FileType.FILES,nameFilter:~/.*\.class/) { file->
System.out.println("find class: "+file.name)
}
}
}
}
}
}
- 将自定义的 LifeCycleTransform 注册到 Gradle 插件中
public class LifeCyclePlugin implements Plugin<Project>{
@Override
void apply(Project project) {
System.out.println("== LifeCyclePlugin Plugin gradle plugin ==")
//注册transform
def android = project.extensions.getByType(AppExtension)
android.registerTransform(new LifeCycleTransform())
}
}
- 再次在命令行中执行 ./gradlew clean assembledebug
命令,可以看到LifeCycleTransform 检索出的所有 .class 文件
> Configure project :app
== LifeCyclePlugin Plugin gradle plugin ==
> Task :app:transformClassesWithZylTransformForDebug
find class: MainActivity.class
find class: BuildConfig.class
BUILD SUCCESSFUL in 7s
问题与总结
- 编译时提示我找不到LifeCycleTransform这个类,原因是LifeCycleTransform这个类当前命名的时候忘记加.groovy文件名后缀了,studio也不报错,显示一切正常
- 由于插件是本地包,你如果测试完gradle插件之后,删除本地插件文件夹,再生成一个带有自定义transform的插件。
- 报错Could not find com.android.tools.build:gradle:3.4.2.,解决办法添加mavenCentral()和google()仓库,注意添加的位置,如下:
apply plugin: 'com.android.application'
apply plugin: 'zyl.asm.lifecycle'
buildscript {
repositories {
//自定义插件的maven地址
maven {url '../asm_lifecycle_repo'}
// 添加这两个仓库为了插件库里面的gradle:3.4.2版本依赖拉取,解决编译报错
//Could not resolve all artifacts for configuration ':app:classpath'. > Could not find com.android.
//Could not find com.android.tools.build:gradle:3.4.2.
mavenCentral()
google()
}
dependencies {
//加载自定义插件 group+module+version
classpath 'com.okay.plugin:asm_lifecycle_pulgin:1.0.0'
}
}
- 检索出的所有 .class 文件不一样多,是项目用到的gradle版本不一样导致的。
- classpath 'com.android.tools.build:gradle:3.6.2'
> Configure project :app
== LifeCyclePlugin Plugin gradle plugin ==
> Task :app:transformClassesWithZylTransformForDebug
find class: MainActivity.class
find class: SizeConvertUtil.class
find class: BuildConfig.class
- classpath 'com.android.tools.build:gradle:3.4.1'
== LifeCyclePlugin Plugin gradle plugin ==
> Task :app:transformClassesWithZylTransformForDebug
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R.class
find class: R.class
find class: R.class
find class: R.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R.class
find class: R$interpolator.class
find class: R$bool.class
find class: R$id.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R$styleable.class
find class: R$style.class
find class: R$anim.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$style.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class
find class: R.class
find class: R.class
find class: R$id.class
find class: R$styleable.class
find class: R$attr.class
find class: R.class
find class: R$interpolator.class
find class: MainActivity.class
find class: R$bool.class
find class: R$id.class
find class: R$mipmap.class
find class: SizeConvertUtil.class
find class: BuildConfig.class
find class: R$styleable.class
find class: R$style.class
find class: R$anim.class
find class: R$string.class
find class: R$color.class
find class: R$dimen.class
find class: R$integer.class
find class: R$layout.class
find class: R$attr.class
find class: R$drawable.class