学习自定义Gradle插件

news/2024/5/20 1:39:26 标签: android, android studio, gradle

自定义 Gradle 插件

  1. 首先新建一个项目
  2. 新建一个module模块,删除无关文件,只需保留main和build.gradle文件即可
  3. gradle文件中删除之前默认所有配置,引入如下配置
//管理仓库的插件
apply plugin: 'maven'
//groovy插件
apply plugin:'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

  1. 在main目录下新建groovy和main文件夹
  2. 在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 ==")
    }
}
  1. 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文件夹

测试插件

  1. 在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文件

  1. gradle插件的基础上,添加依赖
apply plugin: 'maven'
apply plugin:'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
    //添加gradle库
    compile 'com.android.tools.build:gradle:3.6.2'
}
...
  1. 在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)
                   }
                }
            }

        }
    }
}
  1. 将自定义的 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())
    }
}
  1. 再次在命令行中执行 ./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

问题与总结

  1. 编译时提示我找不到LifeCycleTransform这个类,原因是LifeCycleTransform这个类当前命名的时候忘记加.groovy文件名后缀了,studio也不报错,显示一切正常
  2. 由于插件是本地包,你如果测试完gradle插件之后,删除本地插件文件夹,再生成一个带有自定义transform的插件。
  3. 报错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'
    }
}

http://www.niftyadmin.cn/n/1540279.html

相关文章

怎么查公路桩号位置_海南省琼中县基础桩混凝土桩好操作

现代建筑的建设需要基础打桩&#xff0c;为了更好的让基础桩与地面混凝土结构部分衔接&#xff0c;基础桩一般会伸出地面1到2米&#xff0c;使钢筋完整地保留在地面&#xff0c;截桩机是破除基础桩地面桩头混凝土的专用设备。国际上通称pile breaker(破桩机)&#xff0c;为了符…

宏狗和微狗的区别

宏狗的主要功能 1.带有大容量的存储区(1K~63K)&#xff0c;同时内置有2级文件管理系统&#xff0c;开发商可以方便的进行数据存储和模块管理。 2.硬件支持一些标准的加密和签名算法&#xff0c;开发商可以方便的对自己的数据进行加解密和数字签名&#xff0c;防止数据被篡改。 …

2.session 简介

2.session 简介 hibernate的执行流程,创建一个配置对象Configuration&#xff0c;这个配置对象的作用就是用来读取配置文档Hibernate.cfg.xml获得配置对象的目的是可以用它来创建SessionFactory对象&#xff0c;创建SessionFactory对象的时候就会读取相应的里面所加载的这些对象…

借助profiler工具进行内存分析

借助profiler工具进行内存分析官方链接工具说明模拟内存问题场景利用Profiler工具进行内存分析问题解决与总结官方链接 使用 Memory Profiler 查看 Java 堆和内存分配 工具说明 android studio 版本3.6.1 模拟内存问题场景 建立一个新的工程&#xff0c;把下面有问题的自定…

一次性口令设计代码_【项目申报】2019年企业技术中心、工业设计中心认定奖励资金申报工作开始了~...

按照新都区委 区政府《关于推动产业转型升级的意见》(新都委发〔2014〕8号)要求&#xff0c;现将2019年企业技术中心、工业设计中心认定资金奖励申报工作通知如下。一、申报条件工商注册、税收解缴关系在新都区&#xff0c;并于2018年获得省、市企业技术中心、工业设计中心认定…

python 协程可以嵌套协程吗_Python实战异步爬虫(协程)+分布式爬虫(多进程)

引言&#xff1a;我们在写爬虫时常会遇到这样的问题&#xff0c;当需要爬取多个URL时&#xff0c;写一个普通的基于requests库的爬虫程序爬取时间会很长。因为是顺序请求网页的&#xff0c;而网页请求和获得响应过程比较耗费时间&#xff0c;程序不得不等待获得当前网页响应后才…

窄带包络解调python实现_复合材料有限元分析中如何计算损伤包络面积?(附工具)...

复合材料因其组份的多样性和各向异性&#xff0c;导致其构件设计制造阶段和服役使用阶段极易产生缺陷或损伤。在复合材料制作和固化过程中往往存在很多人为因素和工艺质量的不稳定性&#xff0c;这使得复合材料构件的质量具有一定的随机性。另外&#xff0c;在使用过程中&#…

[慢查优化]建索引时注意字段选择性 范围查询注意组合索引的字段顺序

写在前面的话&#xff1a;之前曾说过“不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程”&#xff0c;但对于字段选择性差意味着什么&#xff0c;组合索引字段顺序意味着什么&#xff0c;要求每个人必须了解&#xff1b;重复上一次的话&#xff…