越不懂的越爱装
大家都同等:IT世界没有难不难,只有是否了解过
挑战目录
什么是gradle
是基于Groovy(运行在JVM上的一种语言)的项目构建工具(你说我们写一个jar包来进行项目构建是不是一样的)
- 自动配置依赖的第三方库和jar包
- java源码,res等资源编译打包成apk
- 支持写脚本扩展 编译和打包规则 等
- ...
gradle脚本执行的过程
- 初始化:创建项目实例。如果一个项目有多个build.gradle那么就会为每个模块创建项目实例
- 配置:执行构建脚本,创建并配置任务
- 执行:执行被指定的任务。
脚本构成
-
Project:表示单个脚本文件。xxx.gradle就表示Project为xxx
-
Task:定义在xxx.gradle中的可执行的任务方法, 代表一个构建工作
task myTask task myTask { configure closure } // closure是一个闭包 task myType << { task action } // <<符号是doLast的缩写 task myTask(type: SomeType) // SomeType可以指定任务类型,Gradle本身提供有Copy、Delete、Sync等 task myTask(type: SomeType) { configure closure }
-
Action: doFirst和doLast
-
doFirst:可以在配置阶段后,运行阶段时运行前执行某些操作 (比如在下面的type:Delete的默认执行执行前)
部分同下(改名字即可)
-
doLast:和上面同理,只是在执行后执行某些操作
task myType << { task action } task myType { doLast{task action} } task myType.doLast { task action } task myType(xxx).doLast { task action }
-
doFirst和doLast举例
task order(dependsOn:'a'){ println("test doNormal") //在配置阶段这个就会执行,不管这个任务有没有被运行 doLast { println("test doLast") } doFirst { println("test doFirst") } } task a{ println("a doNormal") //在配置阶段这个就会执行,不管这个任务有没有被运行 doLast { println("a doLast") } doFirst { println("a doFirst") } }
上述的输出为:
18:53:45: Executing task 'order'... Executing tasks: [order] in project E:\project\and\app_temp_new > Configure project :app WARNING: The option setting 'android.enableBuildCache=false' is experimental and unsupported. The current default is 'true' > Configure project :................. > Configure project :base:common WARNING: The option setting 'android.enableBuildCache=false' is experimental and unsupported. The current default is 'true' test doNormal a doNormal > Configure project :................. > Task :base:common:a a doFirst a doLast > Task :base:common:order test doFirst test doLast BUILD SUCCESSFUL in 12s 2 actionable tasks: 2 executed 18:53:57: Task execution finished 'order'.
-
build.gradle在gradle中充当的角色
Gradle默认执行当前目录下的build.gradle文件,代表名字为build的Project
gradle基本语法
-
修饰符:默认是public
-
变量定义:动态推断型(def也可以用来声明方法) def xxx="??" ,直接指定型String xxx="??"
- 全局变量(所以.gradle都能获取)
-
gradle.properties配置文件
//gradle.properties文件 isBuidMode=false
注意:gradle.properties配置文件只能赋值字符串,所以使用的时候需要转型。
比如上面的:
if (isBuidMode.toBoolean()) {
...
} else {
...
} -
ext
-
命令行参数
-
- 局部变量(只有当前.gradle能获取)
- 全局变量(所以.gradle都能获取)
-
可省略的情况:
- 语句后面的分号
- def和变量类型的其中之一(不能全部都省略)
- def和方法的返回值类型的其中之一(不能全部都省略)
- 调用方法时的圆括号
- 方法中的参数类型
- 方法的最后一个表达式可以作为返回值,不需要return语句
-
条件:同java
-
switch :不固定case的类型switch (x){case 多种类型:xxx}
-
断言:assert设置断言,如果为false则会异常退出
-
比较:Groovy的is()方法相当于java的==,==相当于java的equals()。所以比较类时要用a.is(b)
-
循环
-
闭包
-
任务依赖:在执行taskA之前先执行taskB
-
被依赖项定义在依赖项之前
task b << { println 'i am b' } task a(dependsOn: b) << { println 'i am a' }
-
被依赖项定义在依赖项之后(需要使用引号引起来)
task a(dependsOn: 'b') << { println 'i am a' } task b << { println 'i am b' }
-
-
................
Type
从安卓项目中可以看到类似下面的任务
task clean(type: Delete) {
//在配置阶段这个就会执行,不管这个任务有没有被运行
delete rootProject.buildDir //省略括号的方法调用
}
跟踪可以看到如下:
/**
* @return The build directory. Never returns null.
*/
File getBuildDir(); //build文件夹
跟踪delete可以看到如下:
//将build文件夹放到Set<Object> delete中
public Delete delete(Object... targets) { //targets传进来长度为1的 build文件夹目录
for (Object target : targets) {
this.delete.add(target); // private Set<Object> delete = new LinkedHashSet<Object>();
}
return this;
}
上面执行完成后就在配置阶段将build目录添加到delete里面了。
在public class Delete extends ConventionTask implements DeleteSpec里面可以找到如下方法,真正删除build文件夹
@TaskAction //标识在执行这个任务的时候执行该方法
protected void clean() {
Deleter deleter = new Deleter(getFileResolver(), getFileSystem());
final boolean innerFollowSymLinks = followSymlinks;
final Object[] paths = delete.toArray();
setDidWork(deleter.delete(new Action<DeleteSpec>(){
@Override
public void execute(DeleteSpec deleteSpec) {
deleteSpec.delete(paths).setFollowSymlinks(innerFollowSymLinks);
}
}).getDidWork());
}
综上我们可以看出来type: Delete就相当于继承java代码写的Delete任务,继承后我们可以使用相应的方法属性
其他的预定义type :
Copy 、Sync、Zip
上面的可以参照文章预定义type
应用插件
安卓中build.gradle的特定元素
buildscript*:
- 指定项目依赖的仓库地址(repositories)
- 配置使用的插件地址(dependencies)
buildscript {
repositories { //下面是配置仓库中心的多种形式
maven {
credentials {
username NEXUS_USERNAMEy
password NEXUS_PASSWORDy
}
url MAVEN_REPO_RELEASE_URLy
}
flatDir{
dirs '../../base/libs'
}
maven { url 'https://dl.bintray.com/umsdk/release' }
google()
jcenter()
}
dependencies { //配置项目使用插件地址,里面存在很多预定于插件和预定义规则
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "com.alibaba:arouter-register:1.0.2"
//gradle 3.2.1 -> 对应doraemonkit-plugin:3.1.5
classpath 'com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.5'
classpath 'com.bugtags.library:bugtags-gradle:2.1.5'
}
}
allprojects、buildscript、buildscript.repositories、buildscript.repositories.maven等预定于字段
什么是Gradle Wrapper
实质上是一个脚本,自动使用申明版本的gradle
执行构建任务
新建项目时,将gradle-wrapper.jar&gradle-wrapper.properties 拷贝到项目的gradle/wrapper目录
- 配置文件 gradle-wrapper.properties
//指定Wrapper使用的gradle版本。如果本地没有它会去下载在distributionBase+distributionPath路径。 distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip //GRADLE_USER_HOME代表的路径是~/.gradle/文件夹。 distributionBase=GRADLE_USER_HOME //下载放置的路径的一部分 distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
- gradle-wrapper.jar jar包
用来在对应gradle版本不存在时,下载gradle 的jar工具包
常用的Gradle命令
- 查看依赖树:gradle xxx:dependencies (xxx为settings.gradle中include的模块名)
- 查看版本号: gradle -v
- 显示所有的Project: gradle projects
- 显示gradle的gui:
- 显示所有的task: gradle tasks
- 编译执行某个task: gradle Task名
- 静默编译执行某个task: gradle -q Task名
- 编译执行某个Project中的某个task(build.gradle表示build Project其他.gradle文件同理): gradle -b Project名 Task名
- 查找所有的gradle命令: gradle --help
网友评论