生命周期:
1、initalization初始化阶段:
解析整个工程中所有Project,构建所有的Project对应的project对象
2、Configuration 配置阶段:
解析所有的projects对象中的task,构建好所有的task的拓扑图
3、Execution 执行阶段:
执行具体的task及其依赖task
/**
* 配置阶段开始前的监听回调
*/
this.beforeEvaluate {
println '配置阶段开始前.........'
}
/**
* 配置阶段完成以后的回调
*/
this.afterEvaluate {
println '配置阶段完成.........'
}
/**
* gradle执行完毕后的回调监听
*/
this.gradle.buildFinished {
println 'gradle执行完毕.........'
}
this.gradle.beforeProject {
println 'gradle执行之前.........'
}
this.gradle.afterProject {
println 'gradle执行之后.........'
}
this.project.afterEvaluate { project ->
println '配置阶段完成.........'
}
/**
* 获取所有的project
*/
def getProjects() {
println '-------------------------'
println 'Root Project'
println '-------------------------'
this.getAllprojects().eachWithIndex { Project project, int i ->
if (i == 0) {
println "Root project:${project.name}"
} else {
println "+--- project :${project.name}"
}
}
}
this.getProjects()
/**
-------------------------
Root Project
-------------------------
Root project:ParallelSearchGradle
+--- project :app
+--- project :lib_base
+--- project :lib_res
+--- project :module_fun
+--- project :module_me
+--- project :module_search
+--- project :module_thing
+--- project :module_use
-------------------------
**/
/**
* 获取所有的子project
* @return
*/
def getSubProjects() {
println '-------------------------'
println 'Sub Project'
println '-------------------------'
this.getSubprojects().each { Project project ->
println "+--- project :${project.name}"
}
}
this.getSubProjects()
/**
-------------------------
Sub Project
-------------------------
+--- project :app
+--- project :lib_base
+--- project :lib_res
+--- project :module_fun
+--- project :module_me
+--- project :module_search
+--- project :module_thing
+--- project :module_use
**/
**
* 获取根project
* @return
*/
def getMRootProject(){
def name = this.getRootProject().name
println "根project是:${name}"
}
this.getMRootProject()
/**
根project是:ParallelSearchGradle
**/
/**
*在父工程中对子工程进行配置(这里依 app为例,也可以为module_use等)
*/
project('app'){ Project project->
apply plugin: 'com.android.application'
group 'com.fuyao'
version '1.0.0'
dependencies{
}
android{
}
}
/**
* 配置当前结点工程和其subproject的所有project(module)
*/
allprojects {
group 'com.fuyao'
version '1.0.0'
}
println project('module_use').group//com.fuyao
/**
* 不包括当前结点工程,只包括它的subproject(子module)
*/
subprojects {
if (project.plugins.hasPlugin('com.android.library')){
apply from:'../public.gradle'
}
}
/**
* 获取父project
*/
def getParentProject() {
def name = this.getParent().name
println "他的父project 是:${name}"
}
this.getParentProject()
/**
他的父project 是:ParallelSearchGradle
**/
/**
* 获取根project
* @return
*/
def getMRootProject() {
def name = this.getRootProject().name
println "根project是:${name}"
}
this.getMRootProject()
/**
根project是:ParallelSearchGradle
**/
/**
* 扩展属性 在project的build.gradle中进行声明
*/
subprojects {
ext{
compileSdkVersion=28
libSupport='com.android.support:support-v4:28.0.0'
}
}
ext{
minSdkVersion=19
libConstraint='com.android.support.constraint:constraint-layout:1.1.3'
}
或者 新建gradle文件(例:public.gradle)
ext {
android = [targetSdkVersion: 28,
applicationId : 'com.fuyao.parallelsearch']
signconfigs = []
dependence = []
}
在project的build.gradle中引入
//引入公共库
apply from: this.file('public.gradle')
或者在gradle.properties中声明
#************************************公共配置********************************
##最低版本minSdkVersion
MIN_SDK_VERSION=19
##最高版本targetSdkVersion
TAR_SDK_VERSION=28
##编译版本compileSdkVersion
COMPILER_SDK_VERSION=28
##版本号
VERSION_CODE=1
##版本名称
VERSION_NAME=1.0
在module中进行引用
android {
compileSdkVersion this.compileSdkVersion
dataBinding {
enabled = true
}
defaultConfig {
applicationId rootProject.ext.android.applicationId
// minSdkVersion this.project.minSdkVersion
//或者
minSdkVersion this.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode project.VERSION_CODE as int
versionName project.VERSION_NAME
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
....
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation this.libSupport
// implementation this.project.libConstraint
//或者
implementation this.libConstraint
}
/**
* 获取根工程的文件路径
*/
println "root file path==>${getRootDir().absolutePath}"
//root file path==>E:\workspace\work_demo\ParallelSearchGradle
/**
* 获取当前工程build文件路径
*/
println "build file path==>${getBuildDir().absolutePath}"
//build file path==>E:\workspace\work_demo\ParallelSearchGradle\build
/**
* 获取当前工程文件路径
*/
println "project file path==>${getProjectDir().absolutePath}"
//project file path==>E:\workspace\work_demo\ParallelSearchGradle
/**
*从当前gradle中寻找file
* @param path
* @return
*/
def getContent(String path){
try {
def file=this.file(path)//files
//相当于当前的project工程开始查找
return file.text
}catch(Exception e){
println '文件没有找到'
}
}
println getContent('public.gradle')
/**
ext {
android = [targetSdkVersion: 28,
applicationId : 'com.fuyao.parallelsearch']
signconfigs = []
dependence = []
}
**/
/**
* 获取根工程的文件路径
*/
println "root file path==>${getRootDir().absolutePath}"
//root file path==>E:\workspace\work_demo\ParallelSearchGradle
/**
* 获取当前工程build文件路径
*/
println "build file path==>${getBuildDir().absolutePath}"
//build file path==>E:\workspace\work_demo\ParallelSearchGradle\app\build
/**
* 获取当前工程文件路径
*/
println "project file path==>${getProjectDir().absolutePath}"
//project file path==>E:\workspace\work_demo\ParallelSearchGradle\app
/**
* 文件copy
*/
copy {
from file('ceshi.jks')
into getRootProject().getBuildDir()//拷贝到根目录的build下
}
copy {
from file('ceshi.jks')
into getRootDir()//拷贝到根目录下
}
/**
* 拷贝文件夹
*/
copy {
from file('dev/release/')
into getRootProject().getBuildDir().path + "/release/"//拷贝到根目录的build下release中
//筛选不想复制的内容
exclude { details ->
details.file.name.endsWith('.json')
}
//更改文件名称
rename { fileName ->
fileName.replace('parallelsearch', 'huang')
}
}
/**
* 对文件树进行遍历
*/
fileTree('dev/release/') { FileTree fileTree ->
fileTree.visit { FileTreeElement element ->
println "file name==>${element.file.name}"
copy {
from element.file
into getRootProject().getBuildDir().path + "/test/"
}
}
}
tasks.create('apkcopy') {
doLast {
//gradle的执行阶段去执行
def sourcePath = this.buildDir.path + '\\outputs\\apk'
def desationPath = 'C:\\Users\\Administrator\\Desktop\\downloads'
def command = "xcopy /s ${sourcePath} ${desationPath}"
try {
exec {
workingDir 'C:\\Users\\Administrator\\Desktop'
commandLine 'cmd', '/c', command
println "执行外部命令copy成功"
}
} catch (Exception e) {
e.printStackTrace()
println "执行外部命令copy失败"
}
}
}
buildscript {
//配置我们工程的仓库地址
repositories {
jcenter()
mavenCentral()
mavenLocal()
ivy {}
maven {
name 'personal'
url '仓库地址url'
credentials {
username = 'admin'
password = 'admin123'
}
}
}
//配置我们工程的“插件”依赖地址
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
}
}
/**
在android{}中调用
**/
android{
...
sourceSets {
main {
jniLibs.srcDirs = ['libs']//修改so库存放位置
res.srcDirs = ['src/main/res',
'src/main/res-ad',
'src/main/res-buy']//修改res路径
}
}
}
/**
* 在外部调用sourceSets
*/
this.android.sourceSets{
main {
jniLibs.srcDirs = ['libs']//修改so库存放位置
res.srcDirs = ['src/main/res',
'src/main/res-ad',
'src/main/res-buy']//修改res路径
}
}
相关配置均在AndroidSourceSet类中
/**
* task定义,直接通过task函数去创建
*/
task helloTask {
println "定义一个task"
}
task helloTask1(group: 'huang', description: 'task study') {
println "定义一个helloTask1"
}
/**
* task定义,通过TaskContainer去创建Task
*/
this.tasks.create(name: 'helloTask2') {
println "定义一个helloTask2"
}
this.tasks.create(name: 'helloTask3') {
setGroup('huang')//添加分组
setDescription('task study')//添加描述信息
println "定义一个helloTask3"
}
给任务添加group会新增自定义的组方便在as任务列表中找到,否则均在other中
/**
* doFirst使用
*/
task helloTask4(group: 'huang', description: 'task study') {
println "定义一个helloTask4"
doFirst {
println "定义一个helloTask4-doFirst,他的group是:" + group
}
doLast {
println "定义一个helloTask4-doLast,他的group是:" + group
}
}
helloTask4.doFirst {
println "定义一个helloTask4-doFirst,他的description是:" + description
}
helloTask4.doLast {
println "定义一个helloTask4-doLast,他的description是:" + description
}
/**
* 计算build执行时长
*/
def startBuildTime, endBuildTime
this.afterEvaluate {
//保证要找的task已经配置完毕
def preBuildTask = project.tasks.getByName('preBuild')
preBuildTask.doFirst {
startBuildTime = System.currentTimeMillis()
println '开始编译时间:' + startBuildTime
}
def buildTask = project.tasks.getByName('build')
buildTask.doLast {
endBuildTime = System.currentTimeMillis()
println "编译时间:${endBuildTime - startBuildTime}"
}
}
/**
* Task依赖
*/
task exHello {
doLast {
println 'hello'
}
}
task exWorld {
doLast {
println 'world'
}
}
task exMain(dependsOn: exHello) {
doLast {
println 'main'
}
}
//任务多依赖
task exMain1 {
dependsOn exHello, exWorld
doLast {
println 'main'
}
}
task exMain2(dependsOn: [exHello, exWorld]) {
doLast {
println 'main2'
}
}
在被依赖的任务执行完成后才执行当前任务
/**
* 通过运行结果指定依赖
*/
task lib1 {
doLast {
println 'lib1'
}
}
task lib2 {
doLast {
println 'lib2'
}
}
task nolib {
doLast {
println 'nolib'
}
}
task exMain3(dependsOn: [exHello, exWorld]) {
dependsOn this.tasks.findAll {
return it.name.startsWith('lib')
}
doLast {
println 'main3'
}
}
/**
* 执行顺序
*/
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
mustRunAfter taskX
doLast {
println 'taskY'
}
}
task taskZ {
mustRunAfter taskY
doLast {
println 'taskZ'
}
}
按照 taskX ->taskY ->taskZ 顺序执行
/**
* 案例解析版本迭代信息
*/
task handleReleaseFile {
def srcFile = file('releases.xml')
def destDir = new File(this.buildDir, 'generated/release/')
doLast {
println '开始解析版本迭代信息对应的xml文件...'
destDir.mkdir()
def releases = new XmlParser().parse(srcFile)
releases.resource.each { releaseNode ->
//解析每个release结点的内容
def name = releaseNode.versionName.text()
def code = releaseNode.versionCode.text()
def info = releaseNode.versionInfo.text()
//创建文件并写入结点数据
def destFile = new File(destDir, "release-${name}.txt")
destFile.withWriter { writer ->
writer.write("${name}->${code}->${info}")
}
}
}
}
task handleReleaseFileTest(dependsOn: handleReleaseFile) {
def dir = this.fileTree(this.buildDir.path + 'generated/release/')
doLast {
dir.each {
println "file name is: ${it}"
}
println '解析版本迭代信息对应的xml文件测试完成'
}
}
ext {
versionName = '1.0.5'
versionCode = '105'
versionInfo = 'App的第5个版本,上线基本架构核心功能'
destFile = file('releases.xml')
if (destFile != null && !destFile.exists()) {
destFile.createNewFile()
}
}
task writeTask {
//为task指定输入
inputs.property('versionCode', this.versionCode)
inputs.property('versionName', this.versionName)
inputs.property('versionInfo', this.versionInfo)
//为Task指定输出
outputs.file(destFile)
doLast {
def data = inputs.getProperties()
File file = outputs.getFiles().getSingleFile()
//将map传化为实体对象
def versionMsg = new Versionmsg(data)
//将实体对象转换为xml
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)
if (file.text != null && file.text.size() <= 0) {
//文件中没有内容
xmlBuilder.releases {
release {
versionCode(versionMsg.versionCode)
versionName(versionMsg.versionName)
versionInfo(versionMsg.versionInfo)
}
}
file.withWriter { writer -> writer.append(sw.toString()) }
} else {
//已有版本信息
xmlBuilder.releases {
release {
versionCode(versionMsg.versionCode)
versionName(versionMsg.versionName)
versionInfo(versionMsg.versionInfo)
}
}
//将生成的xml数据插到根结点之前
def lines = file.readLines()
def lengths = lines.size() - 1
file.withWriter { writer ->
lines.eachWithIndex { String line, int index ->
if (index != lengths) {
writer.append(line + "\r\n")
} else if (index == lengths) {
writer.append('\r\r\n' + sw.toString() + '\r\n')
writer.append(lines.get(lengths))
}
}
}
}
}
}
class Versionmsg {
String versionCode
String versionName
String versionInfo
}
/**
* 挂接结束执行
*/
this.project.afterEvaluate { project ->
def buildTask = project.tasks.getByName('build')
if (buildTask == null) throw GradleException("build task is not found")
buildTask.finalizedBy "writeTask"
}
task readTask {
inputs.files destFile
doLast {
def file = inputs.files.getSingleFile()
println file.text
}
}
/**
* task 输入输出时默认先执行写,后执行读
*/
task taskTest {
dependsOn readTask, writeTask
doLast {
println '输入输出任务结束'
}
}