初识Gradle
一、Gradle的基本概念
一个开源的项目自动化构建工具,建立在Apache Ant和Apache Maven概念的基础上,并引入了基于Groovy的特定领域语言(DSL),而不再使用XML形式管理构建脚本。同时,gradle还是一个编程框架,可以让开发者使用编程的思想来实现应用构建。gradle的组成:
groovy核心语法
build script block
gradle api
二、Gradle的执行流程
生命周期 | 作用 |
---|---|
Initialzation初始化阶段 | 解析整个工程中所有project(读取setting.gradle文件),构建所有的project对应的Project对象 |
Configuration配置阶段 | 解析所有的project对象中的task,构建好所有task的拓扑图 |
Execution执行阶段 | 执行具体的task及其依赖的task |
生命周期监听:
// 配置阶段开始前的监听回调(即:在Initialzation与Configuration之间)this.beforeEvaluate {}// 配置阶段完成后的监听回调(即:在Configuration与Execution之间)this.afterEvaluate {}// gradle执行完毕后的回调监听(即:在Execution之后)this.gradle.buildFinished {}// 与 this.beforeEvaluate {} 一样this.gradle.beforeProject {}// 与 this.afterEvaluate {} 一样this.gradle.afterProject {}
Gradle中的Project
一、Idea与Gradle 对于project概念的区别
在Idea中,一个项目就是Project,一个Project下可以包含多个模块(Module),一个Module下,又可以有多个Module,其树状结构如下:
虽然可以在Module中继续创建子Module,但一般情况下,我们不会这么做,最多就两层。
+Project --+Module ----+Module ----+Module --+Module --+Module
而对于Gradle而言,Idea中的无论是Project还是Module,都是project,故树状结构如下:
每个project下,都一定会有一个build.gradle
+project // rootProject--+project // subProject----+project ----+project --+project --+project
二、project相关api
api | 作用 |
---|---|
getAllprojects() | 获取工程中所有的project(包括根project与子project) |
getSubProjects() | 获取当前project下,所有的子project(在不同的project下调用,结果会不一样,可能返回null) |
getParent() | 获取当前project的父project(若在rooProject的build.gradle调用,则返回null) |
getRootProject() | 获取项目的根project(一定不会为null) |
project(String path, Closure configureClosure) | 根据path找到project,通过闭包进行配置(闭包的参数是path对应的Project对象) |
allprojects(Closure configureClosure) | 配置当前project和其子project的所有project |
subprojects(Closure configureClosure) | 配置子project的所有project(不包含当前project) |
// rootProject build.gradle下配置:// 1、Project project(String path, Closure configureClosure);project('app') { Project project -> // 一个参数时,可以省略不写,这里只是为了明确参数的类型 apply plugin : 'com.android.application' group 'com.lqr' version '1.0.0-release' dependencies {} android {} }// 2、allprojects(Closure configureClosure)allprojects { group 'com.lqr' version '1.0.0-release'}// 3、subprojects(Closure configureClosure)subprojects { Project project -> if(project.plugins.hasPlugin('com.android.library')){ apply from: '../publishToMaven.gradle' } }
三、属性相关api
1、在gradle脚本文件中使用ext块扩展属性
父project中通过ext块定义的属性,子project可以直接访问使用
// rootProject : build.gradle// 定义扩展属性ext { compileSdkVersion = 25 libAndroidDesign = 'com.android.support:design:25.0.0'}// app : build.gradleandroid { compileSdkVersion = this.compileSdkVersion // 父project中的属性,子project可以直接访问使用 ... } dependencies { compile this.libAndroidDesign // 也可以使用:this.rootproject.libAndroidDesign ... }
2、在gradle.properties文件中扩展属性
hasProperty('xxx'):判断是否有在gradle.properties文件定义xxx属性。
在gradle.properties中定义的属性,可以直接访问,但得到的类型为Object,一般需要通过toXXX()方法转型。
// gradle.properties// 定义扩展属性isLoadTest=truemCompileSdkVersion=25// setting.gradle// 判断是否需要引入Test这个Moduleif(hasProperty('isLoadTest') ? isLoadTest.toBoolean() : false) { include ':Test'}// app : build.gradleandroid { compileSdkVersion = mCompileSdkVersion.toInteger() ... }
四、文件相关api
api | 作用 |
---|---|
getRootDir() | 获取rootProject目录 |
getBuildDir() | 获取当前project的build目录(每个project都有自己的build目录) |
getProjectDir() | 获取当前project目录 |
File file(Object path) | 定位一个文件,相对于当前project开始查找 |
ConfigurableFileCollection files(Object... paths) | 定位多个文件,与file类似 |
copy(Closure closure) | 拷贝文件 |
fileTree(Object baseDir, Closure configureClosure) | 定位一个文件树(目录+文件),可对文件树进行遍历 |
// 打印common.gradle文件内容println getContent('common.gradle')def getContent(String path){ try{ def file = file(path) return file.text }catch(GradleException e){ println 'file not found..' } return null}// 拷贝文件、文件夹copy { from file('build/outputs/apk/') into getRootProject().getBuildDir().path + '/apk/' exclude {} // 排除文件 rename {} // 文件重命名}// 对文件树进行遍历并拷贝fileTree('build/outputs/apk/') { FileTree fileTree -> fileTree.visit { FileTreeElement element -> println 'the file name is: '+element.file.name copy { from element.file into getRootProject().getBuildDir().path + '/test/' } } }
五、依赖相关api
配置工程仓库及gradle插件依赖
// rootProject : build.gradlebuildscript { ScriptHandler scriptHandler -> // 配置工程仓库地址 scriptHandler.repositories { RepositoryHandler repositoryHandler -> repositoryHandler.jcenter() repositoryHandler.mavenCentral() repositoryHandler.mavenLocal() repositoryHandler.ivy {} repositoryHandler.maven { MavenArtifactRepository mavenArtifactRepository -> mavenArtifactRepository.name 'personal' mavenArtifactRepository.url 'http://localhost:8081/nexus/repositories/' mavenArtifactRepository.credentials { username = 'admin' password = 'admin123' } } } // 配置工程的"插件"(编写gradle脚本使用的第三方库)依赖地址 scriptHandler.dependencies { classpath 'com.android.tools.build:gradle:2.2.2' classpath 'com.tencent.tinker-patch-gradle-plugin:1.7.7' } }// ============ 上述脚本简化后 ============buildscript { // 配置工程仓库地址 repositories { jcenter() mavenCentral() mavenLocal() ivy {} maven { name 'personal' url 'http://localhost:8081/nexus/repositories/' credentials { username = 'admin' password = 'admin123' } } } // 配置工程的"插件"(编写gradle脚本使用的第三方库)依赖地址 dependencies { classpath 'com.android.tools.build:gradle:2.2.2' classpath 'com.tencent.tinker-patch-gradle-plugin:1.7.7' } }
配置应用程序第三方库依赖
compile: 编译依赖包并将依赖包中的类打包进apk。
provided: 只提供编译支持,但打包时依赖包中的类不会写入apk。
// app : build.gradledependencies { compile fileTree(dir: 'libs', include: ['*.jar']) // 依赖文件树 // compile file() // 依赖单个文件 // compile files() // 依赖多个文件 compile 'com.android.support:appcompat-v7:26.1.0' // 依赖仓库中的第三方库(即:远程库) compile project('mySDK') { // 依赖工程下其他Module(即:源码库工程) exclude module: 'support-v4' // 排除依赖:排除指定module exclude group: 'com.android.support' // 排除依赖:排除指定group下所有的module transitive false // 禁止传递依赖,默认值为false } // 栈内编译 provided('com.tencent.tinker:tinker-android-anno:1.9.1') }
provided的使用场景:
依赖包只在编译期起作用。(如:tinker的tinker-android-anno只用于在编译期生成Application,并不需要把该库中类打包进apk,这样可以减小apk包体积)
被依赖的工程中已经有了相同版本的第三方库,为了避免重复引用,可以使用provided。
六、外部命令api
// copyApk任务:用于将app工程生成出来apk目录及文件拷贝到本机下载目录task('copyApk') { doLast { // gradle的执行阶段去执行 def sourcePath = this.buildDir.path + '/outputs/apk' def destinationPath = '/Users/lqr/Downloads' def command = "mv -f ${sourcePath} ${destinationPath}" // exec块代码基本是固定的 exec { try { executable 'bash' args '-c', command println 'the command is executed success.' }catch (GradleException e){ println 'the command is executed failed.' } } } }
作者:GitLqr
链接:https://www.jianshu.com/p/eb6f1aff286a
共同学习,写下你的评论
评论加载中...
作者其他优质文章