Gradle终于懂了(一)带你玩转Project

本打算用gradle尝试着去写一些脚本方便项目的构建和打包,但是在复习gradle的时候有了一些新的理解,对gradle的理解不敢说精通,但也更透彻了,可以说是现在终于会写gradle了,所以打算从新写一个系列的文章来做个总结。
之前也发布过一些关于gradle的文章
浅谈Gradle(一)
浅谈Gradle(二)与SourceSet
Gradle排除依赖模块的某个类
Gradle自定义插件实现自定义Task
不要急,我不是让你去看这些东西,我是觉得当我回头去看以前写的这些东西,真的就是弟弟,那都是看大量别人的文章之后总结写出的,那也是别人的东西,怎么说呢,学了之后还是一种似懂非懂的感觉。这次不一样,这次我是看这个来写的,绝对权威绝对官方 https://docs.gradle.org/current/dsl/index.html,因为他本来就是官方。

一. 浏览Gradle官方文档

机翻之后的页面

看到有很多内容,因为不止有android用到gradle嘛,左边还有个目录,入门那些的我们就不管了,进阶的也不管了,毕竟看到这里的多多少少也是写过一些gradle代码的,这章我们主要看这两个


二. gradle构建的生命周期

先简单讲讲生命周期吧,一些简单的东西我就不讲很详细了,比如一个项目有settings.gradle、根目录的build.gradle和模块build.gradle这些,就不详细讲了。
看官网给出的介绍

机翻看得变扭,就不翻译了

看不懂没关系,至少我们能肯定的是构建过程有3个生命周期,Initialization、Configuration和Execution,我建议记住这3个单词,而不要总用中文的初始化、构建、执行去理解。官网下了还良心的给出了个Demo,告诉我们每个生命周期执行的阶段

我不会kotlin所以就只讲groovy,其实差不多的。
Initialization阶段会执行settings里面的代码,Configuration阶段会执行所有build.gradle里面的操作,无论是不是task,Execution阶段会执行action里面的操作(不懂什么是task什么是action的也别急,这里先了解下,往后学就知道了)所以这个Demo下面的内容我们不看,学其它的东西再回来看就豁然开朗了。

三. Project

我们直接讲Project,我记得我刚学gradle的时候经常看到有人写文章说gradle最重要的是Project、task和action,其实这样说确实能让新人很容易上手,却同样也很容易误导别人。
但是从Project入手是不会有错的,真的了解Project是什么之后,你就真正的能看出gradle的架构,到时候task、action什么的就一目了然了。
在上面截图的地方点击进入DSL参考



进来后左边目录有什么 Build script blocks、Core types、 Publishing types、 Container types 之类的,内容很多,但是我们都不管,我们就看project,点击project




进来之后看到Project下面有些概念,英文不好的朋友可以翻译看看这些概念,但是还是要记住他们的单词。
1. project基本概念

(1)Lifecycle 生命周期
(2)Tasks 任务
(3)Dependencies 依赖
(4)Multi-project Builds 多项目构建
(5)Plugins 插件
(6)Properties 属性
(9)Methods 方法

2. 生命周期

生命周期是说,project在Initialization阶段被创建,我们经常在settings.gradle写比如

include ':app'

在Initialization阶段执行这行代码,创建app这个模块的project对象,那就是说一般来说,每个module对应一个project对象。准确来说是gradle根据settings.gradle去找对应module的build.gradle来创建project对象,也就是说project就是build.gradle。
所以project对象对应的代码在哪写,project在哪里创建,这些应该都很清楚了。

3. Methods 方法

task放到之后再写,我更倾向于单独拿一章出来写,其它的也应该分出来讲,要从浅入深,所以先讲Methods,因为它简单。
把project当成一个对象,那这个对象里面有方法就很容易理解吧,先看看一般AS生成的build.gradle是怎样的,也就是project一般是怎样的(我随便找个Demo里面的app模块的代码)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    buildToolsVersion "27.0.0"
    defaultConfig {
        applicationId "com.tencent.tmgp.yybtestsdk"
        minSdkVersion 14
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

我们先不要看android {......}里面的内容,这是plugin(插件)的知识,过滤掉之后

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

是的,整个project里面只剩一个dependencies 方法,这里多嘴说一下,为什么说是方法。这个是一个闭包的写法,不知道的话建议先看看groovy语法中的闭包,一个参数的情况下是能省略括号的。

然后看看project中有什么方法,其实还挺多的

只截了一部分

截图截不完,具体的可以看官网的API https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html
我们随便拿一个方法来说,比如说getName,获取project的名称
就这样写

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

println this.getName()

this就是指这个project嘛,代码会在Configuration生命周期中执行,打印



嗯,我这个Module的名称就叫app,看得不过瘾没关系,我们可以再演示调用多一点的方法

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

println this.getName()
println this.getPath()
println this.getRootDir()
println this.getVersion()

打印结果



而且也能在文档中找到默认生成的dependencies



看到了吧,传的参数是一个闭包(至于闭包里面写什么内容,那就要参照官网文档了)
再比如文档中还有个ant​(Closure configureClosure)方法,那你就能这样写
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

ant{
  ...........
}

那是不是只能在build.gradle里面调用文档中的方法,当然不是,当然也可以自己定义方法

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

println this.getName()
println this.getPath()
println this.getRootDir()
println this.getVersion()

// 定义一个打印的方法
def myfuction(String msg){
    println msg
}
myfuction("6666666")

看结果


上面演示的是在自己内部调用自己的project方法,那在别的project对象中调用该project的方法呢?怎么有点绕,就是一号project调用二号project的方法,要怎么操作。
(为了节省时间,我拿我一个项目来说,这种情况肯定是多模块的情况)

我们先理一下思路,要在一个project调用另一个project的方法要怎么做?当然是先拿到这个project对象,然后再调用它的方法。这时候我们API找到对project的操作(多说一句,看API最好看Javadoc)





比较分散,可能没截完全部,总之在这个API中肯定是能找到的,光看上面的这些方法就知道能拿到所有能获取到的Project,简单说几个
(1)比如getAllprojects(),返回当前的project和子project的集合(子project的意思是比如Moudule的project就是根目录project的子project)
(2)比如getParent()就是获取父project
(3)比如project​(String path)就是根据path获取project,有的人会问我怎么懂path是什么,没关系,你可以在对应的project中调用getPath()打印,就知道这个project的path是什么了(一般都是:app)。
还有很多方法能获取到相对应的project。
假如我在名为test的project中调用:app的project

println "测试 "+project(":app").getRootDir()

获取:app的根目录的地址,这样就行了,看得出什么不。
project(":app").getRootDir() 和 this,getRootDir() 得到的结果是一样的,因为他们都是同一个根目录下。

4. Properties

文档中也有个Properties文档



截不完图,详细的可以看文档,比如属性中有个常用的属性name,可以直接在project中获取。

println "属性name "+name

如果我们直接设值的话呢

name = "mytest"
println this.getName()

会提示这个属性是只读的属性。
想看关于这些属性更详细的信息的话,可以在文档下面找到Property details


只截取一部分图

你会发现属性后面有个只读的提示,name属性也是,所以无法直接这样修改属性。

还有有个额外属性操作,就是ext关键字。
在A的project中定义

ext.testStr = "test 66666666666666"

在B的project中调用

println project(":app").ext.testStr

这里先简单了解下这些原有的属性就行,在讲到插件的时候会解释更多。

project就大概先提到这些吧,其它内容在讲到task、dependencies和plugin也会提到一些相关的内容,学了project的生命周期和一些属性、方法之后,对project相信也会有一定的了解。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容