Android Gradle 生命周期 : 自动化打包失败所引出的Gradle生命周期问题

背景

前段时间在搞Android自动化打包的事情。
我们的library是需要提供给其他团队使用的,所以在使用Jenkins自动化打包过程中,需要将library打包成aar并发布到maven仓库上。

所以对于打包,我们需要先将myLibrary打包成aar并发布到maven仓库上,再清空app的缓存,并将app打包成apk
对应gradle命令如下

gradlew myLibrary:clean myLibrary:uploadArchives app:clean app:assembleRelease

按原先的理解来说,gradle在执行命令的时候,会顺序执行,会先执行myLibrary:clean,再执行myLibrary:uploadArchives,然后执行app:clean,最后执行app:assembleRelease
在项目的依赖没有问题的时候,确实是没有问题的。
但是,由于我们是先上传myLibrarymaven仓库,然后app再去获取最新的myLibrarymaven依赖,这个过程中,当myLibrary上传maven 仓库成功后,会自动将myLibrary的maven依赖的版本号+1

这个具体看我的另一篇博客 Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖

这个时候就出问题了,会发现直接就报找不到依赖的错误了

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:lintVitalRelease'.
> Could not resolve all artifacts for configuration ':app:debugCompileClasspath'.
   > Could not find com.heiko.test:myLibrary:2.0.99.
     Required by:
         project :app

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

这是为什么呢 ?
按gradle执行命令的顺序,按之前的理解是会先执行myLibrary:uploadArchivesaar上传到maven仓库,这时候再去执行app:assembleRelease 应该已经可以取到最新的依赖了才对呀 ?

测试

百思不得其解之际,写了一个gradledemo,对task的相关方法进行了打印

task myTask1 {
    configure {
        println("myTask1:configure")
    }
    doFirst {
        println("myTask1:doFirst")
    }
    doLast {
        println("myTask1:doLast")
    }
}

task myTask2 {
    configure {
        println("myTask2:configure")
    }
    doFirst {
        println("myTask2:doFirst")
    }
    doLast {
        println("myTask2:doLast")
    }
}

task myTask3 {
    configure {
        println("myTask3:configure")
    }
    doFirst {
        println("myTask3:doFirst")
    }
    doLast {
        println("myTask3:doLast")
    }
}

然后我们使用命令行来执行myTask1myTask2 myTask3

gradlew myTask1 myTask2 myTask3

可以看到执行结果

Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details

> Configure project :
myTask1:configure
myTask2:configure
myTask3:configure

> Task :myTask1
myTask1:doFirst
myTask1:doLast

> Task :myTask2
myTask2:doFirst
myTask2:doLast

> Task :myTask3
myTask3:doFirst
myTask3:doLast

BUILD SUCCESSFUL in 5s
3 actionable tasks: 3 executed

这时,可以发现gradle会先去执行所有taskconfigure方法,再去真正依次执行各个task

gradle的生命周期

这就引申出gradle的生命周期了

在这里插入图片描述

  • initialization:初始化阶段
    • 执行工程的setting.gradle文件
    • 解析整个工程下的所有Project,构建所有的Project对应的project对象
  • Configuration:配置阶段
    • 解析所有的Projects对象中的task,构建好所有task的依赖图 (执行的先后顺序)
  • Excution:执行阶段
    • 执行具体的task及依赖task (先执行目标Task依赖的Task,再执行目标Task)

这里说明一下
Project : 每个build.gradle 就对应一个project,Project里可以有多个Task
Task : 主要的工作执行者,每个Task由多个Action组成

我们在settings.gradle中打印一句日志
在这里插入图片描述
再执行一下gradlew myTask1 myTask2 myTask3,可以看到执行顺序

在这里插入图片描述

解决方案

知道了这个概念我们就可以知道,所有gradle task在执行之前,都会先执行所有task的configure,进行配置。
所以,我们必须要把上面的这个gradle命令进行拆分。

步骤一 : 清空myLibrary的缓存,并将myLibrary打包成aar并发布到maven仓库上

gradlew myLibrary:clean myLibrary:uploadArchives

步骤二 : 清空app的缓存,并将app打包成apk

gradlew app:clean app:assembleRelease

这样子执行,就不存在最初说的那个问题了。
Jenkins是支持创建多个gradle执行命令的,所以是不需要把gradlew命令杂糅在一起,是可以拆分开来分步骤执行的,这个也是我们前期踩坑的地方。

重新配置好Jenkins,就可以继续搞我们的自动化打包了,详见 Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

氦客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值