第十章 gradle自动化构建系列文章 之 gradle中的project

第十章 gradle自动化构建系列文章 之 gradle中的project

< center>

查看 “Android自动化构建系列” 全部文章

gradle 相对于maven,ant的强大之处在于可以变成控制构建的整个流程,不再局限于xml配置文件

gradle项目和我们平时理解的 AndroidStudio 项目不同,从gradle执行的角度理解,每一个moudle都是一个独立的project,包括最外层的project 也是project, 里面的task都是独立存在的

1. gradle 运行中的三个过程

初始化: 解析setting.gradle,获取所有的project

**配置:**通过扫描所有project中的build.gradle文件获取所有的task,形成有线无环图形成先后执行依赖关系

执行task: 按照上面的顺序执行所有的task

  • 上面的三个过程对应三个色块

2. gralde生命周期的监听实现

2.1 初始化

  • 初始化其实就是在执行 setting.gralde 所以初始化你希望做的事情就可以写在 setting.gralde 这个文件里,运行的时候就会在gradle指令初始化的时候执行

2.2 配置阶段开始之前的监听,project级别的,每个project中的监听都会执行一次,执行的顺序和setting中inculde 顺序一样

/**
 * 配置阶段开始前的回调
 */
this.beforeEvaluate {
    println "app初始化完成..."
}

2.3 配置阶段完成阶段的监听,project级别的,每个project中的监听都会执行一次,执行的顺序和setting中inculde 顺序一样

/**
 * 配置阶段完成以后的回调
 */
this.afterEvaluate {
    println 'app配置完成...'
}

2.4 执行阶段执行完毕的监听,project级别的,每个project中的监听都会执行一次,执行的顺序和setting中inculde 顺序一样

/**
 * gradle指令执行完成后回调
 */
this.gradle.buildFinished {
    println 'app执行阶段执行完毕...'
}
  • 结合一个案例理解下:

setting中配置项目 include 顺序,同时输出一句话,证明初始化时读取了setting

app工程中build.gralde的配置

appLibrary工程中build.gralde的配置

运行得到结果:

project的详解

  • 从gradle的角度看,gradle的管理是树状结构的,最外层的是根project,下面挂在的是子project
  • 每一个子project都会对应输出,或输出apk,war,libs等等这个依赖配置完成
  • 同时每个project的配置是依靠自己的build.gradle完成的

通过命令行 gradle projects 可以验证

本章节主要学习

1. project相关的api

1.1 this.allprojects 获取跟项目下所有的工程,返回一个集合

	/**
	 * 手动 实现一个获取项目下所有project的方法
	 */
	task getAllProject << {
	
	    println '''
		------------------------------------------------------------
		Root project
		------------------------------------------------------------
		'''
	
	    this.allprojects.eachWithIndex { project, index ->
	        if (index == 0) {
	            println "Root project ${project.name}"
	        }else {
	            println "+-------- Project ${project.name}"
	
	        }
	
	    }
	
	}

执行task

gradle getAllProject

输出结果:

源码说明:

1.2 this.subprojects 获取跟项目下所有子工程,返回一个集合

	/**
	 * 手动 实现一个获取项目下所有子project的方法
	 */
	task getSubProject << {
	
	    println '''
		------------------------------------------------------------
		Sub project
		------------------------------------------------------------
		'''
	
	    this.subprojects .eachWithIndex { project, index ->
	
	            println "+-------- Project ${project.name}"
	
	    }
	}

执行task

gradle getSubProject

输出结果:

1.3 this.rootProject 获取根项目

/**
 * 手动 实现一个获取项目根project的方法
 */
task getRootPro << {

    println '''
	------------------------------------------------------------
	Root project
	------------------------------------------------------------
	'''

    println "+-------- Root project ${this.rootProject.name}"
    
}

执行task

gradle getRootPro

输出结果:

1.4 this.getParent() 父节点工程 没有返回null

/**
 * 手动 实现一个获取项目父project的方法
 */
task getParentPro << {

    println '''
	------------------------------------------------------------
	Parent project
	------------------------------------------------------------
	'''

    println "+-------- Parent project ${this.getParent().name}"

}

2. project 的相关配置

2.1 project(“app”)从当前节点下(包括当前节点)查找名称对应的project

app.build 中定义获取version的方法

	/**
	 * 输出当前的version
	 */
	def printVersion () {
	    return version
	}

rootProject配置代码

/**
 * 根据projectd的名称查找对应的project
 *
 */
task findTheProject() << {
    this.project("app") { project ->
        println '''
		------------------------------------------------------------
		获取单个 project ,并进行操作
		------------------------------------------------------------
		'''

        project.version='1.0.1'
        println "当前操作的 project 是 ${project.name}"
        println "当前配置后的版本号是 ${project.printVersion()}"

		//指定当前project的输出结果为apk
		apply  plugin: "com.android.application"
    }
}

运行结果:

应用场景:

  • 在根project中获取任意一个子project对其进行配置,比如我们在例子中单独配置这个project的version

2.2 allprojects配置当前节点project和当前节点下的所有子节点project

appLibrary.build 中定义获取version的方法

	/**
	 * 输出当前的version
	 */
	def printVersion () {
	    return version
	}

rootProject配置代码

/**
 * 配置当前节点project及其所有的子project
 */
task configAllProject << {

    allprojects {
        version = '1.0.8'
        println "全局配置后 appLibrary 的Version是 ${this.project('appLibrary').printVersion()} "
    }

}

运行结果:

当然在实际的使员过程中,allProject的配置直接放在文件中定义,不必放在一个task中
细心的朋友会发现我们的项目被调用了三次,只是因为allProject 返回的是一个project的集合,默认省略了回调参数project
如下是标准的写法

/**
 * 配置当前节点project及其所有的子project
 */
task configAllProject << {

    allprojects { project->
        println "当前配置的project是 ${project.name}"
        version = '1.0.8'
        println "全局配置后 appLibrary 的Version是 ${this.project('appLibrary').printVersion()} "
    }

}

运行结果:

相信这样你就明白整个配置过程了,allProject本质其实就是一个方法,方法的参数只有一个闭包,因此可以把闭包写在外面,方法执行时遍历所有的project然后调用闭包进行 project.变量的赋值或者方法的调用,只用当对应的appLibrary被调用的时候,version才会被赋值

2.3 subprojects配置当前节点下所有子节点的project

subprojects {
    println "当前配置的project是 ${it.name}"
    version = '1.1.8'
    println "全局配置后 appLibrary 的Version是 ${this.project('appLibrary').printVersion()} "
}

运行结果:

明白了上面的那个方法,这个方法就不用过多的解释了

应用场景

 subprojects {Project project ->
       
     version = '1.1.8'
      

     //模拟实际用用的场景,将编译好的lib发送到maven仓库
     if(project.plugins.hasPlugin('com.android.library')){
         //依赖(引入)一个事先编辑的脚本文件,上传文件到Maven
         apply from: 'publishToMaven.gradle'
     }

 }

查看 “Android自动化构建系列” 全部文章

你可能感兴趣的:(gradle构建工具系列)