# GradleDemo **Repository Path**: geguol.cc/GradleDemo ## Basic Information - **Project Name**: GradleDemo - **Description**: 入门了DSL 能看懂 会查文档 OK - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-03-30 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Gradle [gradle blog](http://android.jobbole.com/81436/) ## 我的理解 1. 执行过程~初始化~配置~运行task 2. 对应三种~setting~app~lib(.gradle) 3. 三种对象gradle(1个),project(n),setting1 4. 每个script block都是一个闭包 5. 所有的SB都在run方法中运行,def为对应类的成员函数 6. ext作配置 7. << 重载doLast 在task最后执行 8. project也有doLast ### 这里要强调一点: > - Task 和 Task 之间往往是有关系的,这就是所谓的**依赖关系**。 > - 比如, assemble task就**依赖其他 task先执行**,assemble**才能完成最终的输出**。 > - 依赖关系对我们使用 gradle 有什么意义呢? > 如果知道 Task 之间的依赖关系,那么开发者就**可以添加一些定制化的 Task**。 > - 比如我为 assemble 添加一个 SpecialTest 任务,并指定 assemble 依赖于 SpecialTest。 > 当 assemble 执行 的时候,就会先处理完它依赖的 task。自然,SpecialTest 就会得到执行了... ### Gradle的配置流程 1. 初始化 Setting会先执行 2. 配置 遍历所有的Project 并生成Task之间的依赖关系图 3. 执行所有的Task > 本质上所有的gradle配置都是函数调用 ### 核心对象 > Gradle对象:当我们执行gradle xxx或者什么的时候,gradle会从默认的配置脚本(根目录下的gradle)中构造出一个Gradle对象。在整个执行过程中,只有这么一个对象。Gradle对象的数据类型就是Gradle。我们一般很少去定制这个默认的配置脚本。 > Project对象:每一个build.gradle会转换成一个Project对象。 > Settings对象:显然,每一个settings.gradle都会转换成一个Settings对象。 1. gradle对象 类似于Object超类 存在所有对象中的一个成员对象 [https://docs.gradle.org/current/dsl/org.gradle.api.invocation.Gradle.html](https://docs.gradle.org/current/dsl/org.gradle.api.invocation.Gradle.html) 2. project对象 每个xxx.gradle 文件都会生成一个project对象 > 加载插件 > 配置属性 [https://docs.gradle.org/current/dsl/org.gradle.api.Project.html](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html) > 构建顺序 ``` 老子是top-level ================================== ================================== 老子是:app ================================== Incremental java compilation is an incubating feature. ================================== 老子是:posdevice ================================== ``` 3. Setting对象 由Setting.gradle 文件生成的对象 >Setting对象地址 [https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html](https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html) ### gradle 解析生命周期 > 在执行gradle的时候解析各个gradle的顺序 ## gradle 常用指令: - **gradle assemble** 这个task将会组合项目的所有输出。 > assembleDebug (aD) > assembleRelease (aR) - **gradle check** 这个task将会执行所有检查。 - **gralde build** 这个task将会执行assemble和check两个task的所有工作 - **gradle clean** 是执行清理任务,和 make clean 类似。 - **gradle properites** 用来查看所有属性信息 - **gradle tasks**会列出每个任务的描述,通过描述,我们大概能 知道这些任务是干什么的.....。(在所有的文件夹下都一样) - **gradle task-name** 执行它就好。 ## Task(project 的一个task函数返回Task对象) ``` task myTask task myTask { configure closure } task myTask(type: SomeType) task myTask(type: SomeType) { configure closure } ``` > 一个Task包含若干Action。所以,Task有doFirst和doLast两个函数,用于添加需要最先执行的Action和需要和需要最后执行的Action。Action就是一个闭包。 > Task创建的时候可以指定Type,通过type:名字表达。这是什么意思呢? 其实就是告诉Gradle,这个新建的Task对象会从哪个基类Task派生。 比如,Gradle本身提供了一些通用的Task,最常见的有Copy 任务。 Copy是Gradle中的一个类。当我们:task myTask(type:Copy)的时候, 创建的Task就是一个Copy Task。 > 当我们使用 task myTask{ xxx}的时候。花括号是一个closure。这会导致gradle在创建这个Task之后,返回给用户之前,会先执行closure的内容。 > 当我们使用task myTask << {xxx}的时候,我们创建了一个Task对象,同时把closure做为一个action加到这个Task的action队列中,并且告诉它“最后才执行这个closure”(注意,<<符号是doLast的代表)。 ## task 关联关系 * finalizedBy * dependsOn * mustRunAfter ## 根top-level 配置subproject ``` //下面这个subprojects{}就是一个Script Block subprojects { println"Configure for $project.name" //遍历子Project,project变量对应每个子Project buildscript { //这也是一个SB repositories {//repositories是一个SB ///jcenter是一个函数,表示编译过程中依赖的库,所需的插件可以在jcenter仓库中 //下载。 jcenter() } dependencies { //SB //dependencies表示我们编译的时候,依赖android开发的gradle插件。插件对应的 //class path是com.android.tools.build。版本是1.2.3 classpath'com.android.tools.build:gradle:1.2.3' } //为每个子Project加载utils.gradle 。当然,这句话可以放到buildscript花括号之后 applyfrom: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle" }//buildscript结束 } ``` ## Script Block > Configure xxx for this project > 作用是配置当前的project 每个sb(DEL Refrence)都对应一个 函数(javadoc) root/build.gradle ``` buildscript { /* * The given closure is executed against this project's ScriptHandler. * The ScriptHandler is passed to the closure as the closure's delegate. * 这个闭包是在ScriptHandler 对象中执行的,所以可以访问 ScriptHandler中的sb * * ScriptHandler对象的方法: * * dependencies(Closure configureClosure) * Configures the dependencies for the script. * repositories(Closure configureClosure) * Configures the repositories for the script dependencies * * */ // println this.project.buildscript.getClass().name 证明被 DefaultScriptHandler 对象调用 repositories { // 在sb 中声明 在DefaultScriptHandler对象中调用 jcenter() } dependencies { /* * 交给 DependencyHandler 执行 * */ classpath 'com.android.tools.build:gradle:2.2.3' } } ``` 说明: 所有的scriptblock 都在 Project DEL 中定义 如何找到 这些sb的嵌套关系 首先找到SB 的代理对象 然后在javaDoc 中找到 代理对象的函数 关注 参数为Closer 的函数 对应的函数名称就是sb名称 以此类推... ## Android 插件 [Android Plugin API](http://google.github.io/android-gradle-dsl/current/) Manifest entries ``` Through the DSL it is possible to configure the most important manifest entries, like these: minSdkVersion targetSdkVersion versionCode versionName applicationId (the effective packageName -- see ApplicationId versus PackageName for more information) testApplicationId (used by the test APK) testInstrumentationRunner ``` ### 关于android > sourcesets> main > The Java plugin defines two standard source sets, called main and test. > The main source set contains your production source code, which is compiled and assembled into a JAR file. > The test source set contains your test source code, which is compiled and executed using JUnit or TestNG. > These can be unit tests, integration tests, acceptance tests, or any combination that is useful to you. 这里main 不是sourcesets的一个函数;DSL 和 DOC中死活找不到 类似的还有 buildTypes > 默认 release 和 debug > 可以自己添加 ``` buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug{ minifyEnabled false } other{ minifyEnabled false } } ``` 然而 这样的原理解释: Closer 下 多个方法(三个闭包) 这样可以理解为:buildTypes 像是一个集合 事实证明: NamedDomainObjectContainer NamedDomainObjectContainer NamedDomainObjectContainer 都是集合 Collection, org.gradle.util.Configurable>.... Ok ## 参考文档 [邓老师](http://android.jobbole.com/81436/) [GroovyJDK](http://docs.groovy-lang.org/latest/html/groovy-jdk/) [GradleDSL](https://docs.gradle.org/current/dsl/) [AndroidPluginDSL](http://google.github.io/android-gradle-dsl/current/index.html)