《Gradle 权威指南》读书笔记——第四章 Gradle 任务

8 篇文章 0 订阅
6 篇文章 0 订阅

多种方式创建Gradle任务
在Gradle中我们可以有多种方式在创建任务

//1.直接以一个任务的名字创建任务

    def Task myTask1=task(myTask1Do)
    myTask1Do.doLast{
        println "myTask1Do.doLast"
    }

//2.以一个任务的名字+一个对该任务的配置map来创建task实例

    def Task myTask2=task(myTask2Do,group:BasePlugin.BUILD_GROUP)
    myTask2Do.doLast{
        println "myTask2Do=$myTask2Do.group"
    }

//3.闭包方式

    task myTask3Do{
        //闭包中的委托对象是task,description是task的属性
        description '描述'
        doLast{
            println "myTask3Do:$description"
        }
    }

多种方式访问task

//1.task在创建时,会作为project的属性添加到project上,所以我们可以通过任务名字来定义和使用task
task mytask
//[]在Groovy是操作符,是getAt()的重载
tasks["mytask"].doLast{
    println"mytask"
}

​
//2.通过路径访问
task.findByPath(":多方式访问Task:mytask").doLast{
    println "mytask.findByPath" //找不到返回null
}
task.getByPath(":多方式访问Task:mytask").doLast{
    println "mytask.findByPath" //找不到抛出UnKnownTaskException
}
//当我们拿到task的引用的时候,就可以按照我们的业务逻辑去操纵它,比如配置任务依赖,配置一些属性

任务的分组和描述
任务的分组其实就是对任务的分类,便于我们对任务进行归类整理;
任务的描述其实就是说明这个任务有什么用;

//建议在创建任务的时候对这两个属性都要配置
task myTask{
    description "description的demo"
    group=BasePlugin.BUILD_GROUP
    doLast{
        println"description:$description,group=$group"
    }
}

当我们使用gradle tasks查看任务的时候就可以发现该任务被分类到BuildTasks中去了
使用IDE似乎鼠标悬停到任务上也可以看到描述

操作符的重载
我们都知道<< 和doLast的效果是相同的,但是为什么呢?
task <<

//那么为什么left.shift的效果和doLast相同呢?
//源码:
public Task doLast(final Closure action){
    hasCustomActions=true;
    if(action==null)
        throw new InvalidUserDataException("Action must not be null")
    taskMutator.mutate("Task.doLast(Closure)",new Runnable(){
        public void run(){
            action.add(convertClosureToAction(action))
        }
    })  
}
public Task leftShift(final Closure action){
    hasCustomActions=true;
    if(action==null)
        throw new InvalidUserDataException("Action must not be null")
    taskMutator.mutate("Task.leftShift(Closure)",new Runnable(){
        public void run(){
            action.add(convertClosureToAction(action))
        }
    })  
}
//可以发现这两个方法的关键都是actions.add(),所以他们的效果其实都是一样的

任务的执行分析
指定Task其实就是遍历执行actions List
@TaskAction标齐的方法会被作为action,然后通过task的prependParallelSafeAction被放到actionList中

Task mytask= task mytask1(type:CustomTask)
mytask.doFirst{
    println"doFirst"
}
mytask.doLast{
    println"doLast"
}
​
class CustomTask extends DefaultTask{
//TaskAction注解表明是主体方法,只能在类中的定义主体方法
    @TaskAction
    def doSelf(){
        println "doSelf"
    }
}

结果
Task执行之前执行doFirst
Task本身执行doSelf
Task执行之后执行doLast

任务的排序
通过task.shouldRunAfter
task.mustRunAfter来控制任务的执行顺序

task mytask1 <<{
    println "mytask1"
}
task mytask2 <<{
    println "mytask2"
}
//依赖的顺序不当的话
//Circular dependency between the following tasks:
​
//强制要求
mytask1.mustRunAfter mytask2
//非强制要求,不一定会按照该顺序执行
mytask2.shouldRunAfter mytask1

任务的禁用和启用
task中有一个enable属性,默认true,为false时,执行该方法会提示该任务被跳过

task mytask {
    println"mytask"
}
mytask.enabled=false //SKIPPED

onlyIf断言
Task.onlyIf(Closure),该闭包返回false则跳过

final String ALL="all"
final String MAIN="main"
final String OTHERS='other'
​
project.ext{
    build_apps=ALL
}
​
task yingyongbao {
    println "打应用宝的包"
}
yingyongbao.onlyIf{
    def flag=true
    if(project.hasProperty("build_apps")){
        Object buildType=project.property("build_apps")
        if(ALL.equals(buildType)||MAIN.equals(buildType)){
            flag=true
        }else{
            flag=false
        }
    }
    flag
}
​
task huawei << {
    println "打华为的包"
}
huawei.onlyIf{
    def flag=true
    if(project.hasProperty("build_apps")){
        Object buildType=project.property("build_apps")
        if(OTHERS.equals(buildType)||ALL.equals(buildType)){
            flag=true
        }else{
            flag=false
        }
    }
    flag
}
​
task sixty <<{
    println "打360的包"
}
sixty.onlyIf{
    def flag=true
    if(project.hasProperty("build_apps")){
        Object buildType=project.property("build_apps")
        if(OTHERS.equals(buildType)||ALL.equals(buildType)){
            flag=true
        }else{
            flag=false
        }
    }
    flag
}
task build 
​
build.dependsOn yingyongbao,huawei,sixty

通过 build_apps 属性控制我们要打哪些包
#打所有的渠道包
./gradlew  :example48:build
./gradlew  -Pbuild_apps=all :example48:build
​
#打首发包
./gradlew  -Pbuild_apps=shoufa :example48:build
​
​
#打非首发包
./gradlew  -Pbuild_apps=exclude_shoufa :example48:build
​

任务的规则
我们创建的任务都在TaskContainer中,是由其进行管理的.
TaskContainer继承于NamedDomainObjectCollection,NamedDomainObjectCollection是唯一一个具有唯一不变名字的域的对象的集合,它里面所有的元素都具有唯一不变的名字:String,所以我们可以通过名字获取该元素.
添加自定义规则:一个是直接添加一个rule ,一个是通过闭包配置成一个Rule 再添加。

  /**
     * Adds a rule to this collection. The given rule is invoked when an unknown object is requested by name.
     *
     * @param rule The rule to add.
     * @return The added rule.
     */   
    Rule addRule(Rule rule);
​
    /**
     * Adds a rule to this collection. The given closure is executed when an unknown object is requested by name. The
     * requested name is passed to the closure as a parameter.
     *
     * @param description The description of the rule.
     * @param ruleAction The closure to execute to apply the rule.
     * @return The added rule.
     */
    Rule addRule(String description, Closure ruleAction);


规则的作用:
当查找不到我们要查找到的任务的时候,就会调用我们添加的规则来处理这种异常情况
源码可知,通过addRule(String,Closure)来配置规则.
当我们执行依赖一个不存在的任务时,Gradle会执行失败,通过编写规则我们可以改成打印提示信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Annoke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值