Gradle插件在项目中的应用方式

Gradle基础概念

  • projects ( 项目 ):每一个构建都是由一个或多个 projects 构成的,安卓工程每个module工程就是一个project,对应的是module里面的build.gradle文件
project.png
  • tasks ( 任务 ):每一个 project 是由一个或多个 tasks 构成的. 一个 task 代表一些更加细化的构建
task.png

Gradle 扩展

如上图project,project是实现了ExtensionAware的。ExtensionAware的getExtensions方法返回了一个ExtensionContainer,也就是一个可以扩展容器。通过ExtensionContainer我们可以去创建扩展。

org.gradle.api.tasks.TaskContainer接口:
//查找task
findByPath(path: String): Task
getByPath(path: String): Task
getByName(name: String): Task
withType(type: Class): TaskCollection
matching(condition: Closure): TaskCollection

//创建task
create(name: String): Task
create(name: String, configure: Closure): Task 
create(name: String, type: Class): Task
create(options: Map<String, ?>): Task
create(options: Map<String, ?>, configure: Closure): Task
ExtensionAware.png
ExtensionContainer.png
extuse.png

按照文档,我们来试试

set.png

注释掉配置里面的内容,我们再看看运行打印结果

notset.png

从上图可以看出,如果我们没有配置,就会使用默认的,这种配置的写法是不是似曾相识,譬如我们经常要改动的android{}里面的版本号之类的,android 它就是一个 Extension,看看源码就知道android 实际就是 AppExtension 这个类。所以 android 能配置什么属性就可以在 AppExtension查找即可。

/**
 * Gradle plugin class for 'application' projects.
 */
public class AppPlugin extends BasePlugin implements Plugin<Project> {
    
    protected BaseExtension createExtension(
            @NonNull Project project,
            @NonNull Instantiator instantiator,
            @NonNull AndroidBuilder androidBuilder,
            @NonNull SdkHandler sdkHandler,
            @NonNull NamedDomainObjectContainer<BuildType> buildTypeContainer,
            @NonNull NamedDomainObjectContainer<ProductFlavor> productFlavorContainer,
            @NonNull NamedDomainObjectContainer<SigningConfig> signingConfigContainer,
            @NonNull ExtraModelInfo extraModelInfo) {
        return project.getExtensions()
                .create(
                        "android",//"android" 就是 Extension 的名字
                        AppExtension.class,
                        project,
                        instantiator,
                        androidBuilder,
                        sdkHandler,
                        buildTypeContainer,
                        productFlavorContainer,
                        signingConfigContainer,
                        extraModelInfo);
    }


Gradle 本地脚本插件

有时候我们不希望很多把很多gradle脚本写在build.gradle里面,通过apply就可以依赖本地其他gradle文件,就如同java里面import一样

localgradle.png

Gradle 远程脚本插件

其实和本地插件一样,只不过是依赖的远程http的url地址。有时候有些脚本我们需要动态的改变的时候使用这种方法,譬如我们的依赖组件的版本号统一管理,所有同一个版本发布的组件引用同一个分支的远程gradle文件。

gitplugin.png
remoteplugin.png

Gradle 二进制插件

Gradle插件主要是实现Plugin接口apply方法,下面是之前我写的一个检测项目中图片是否全部是webp的插件,因为webp体积小,用于体积优化的任务插件

  1. 在项目工程的根目录下创建buildSrc目录,这个名字不能错,必须是buildSrc。创建完之后,rebuild一下工程,会在buildSrc下生成一些目录
  2. 在buildSrc目录下创建build.gradle.kts文件,用kotlin写插件
kotlingradle.png
plugins {
    `kotlin-dsl`
}
repositories {
    jcenter()
}
  1. 在buildSrc目录下创建src/main/kotlin目录,目录名字一定不要错!!!,然后编写插件
taskImpl.png
  1. 在 main 目录下新建 resources 目录,然后在 resources 目录里面再新建 META-INF 目录,再在 META-INF 里面新建 gradle-plugins 目录。最后在 gradle-plugins 目录里面新建 properties 文件,注意这个文件的命名,你可以随意取名,但是后面使用这个插件的时候,会用到这个名字。比如,你取名为com.example.harry.properties,那么这个插件的id就是com.example.harry
resource.png
  1. 在app中进行引用
taskrun.png
  • 我们还可以通过另一种方式来生成插件
gradlePlugin {
    plugins {
        create("HarryPlugin2") {
            //插件id,用于引用插件,如:apply plugin: 'id'
            id = "com.example.harry2"
            //指定插件的实现类
            implementationClass = "com.example.harry.HarryPlugin2"
        }
    }
}
plugin2.png
  • 我们还可以通过这个buildSrc包来进行依赖管理
deps.png
depimpl.png

独立插件maven的发布

  • 直接新建一个module,不需要以buildSrc命令。新建module默认的gradle里面内容删除掉,添加maven依赖,编写插件后即可发布本地maven仓库
maven.png

发布完成后即可在项目中引用


mavenapply.png

上面是使用的本地仓库,如果有maven服务器,将url替换成远程maven即可。maven服务搭建请点击这里

文中代码地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容