Gradle系列分2章
上篇Android Gradle Groovy自动化构建入门篇
下篇Android Gradle Groovy自动化构建进阶篇html
上篇,咱们已经介绍了Gradle的基本语法,接下来让咱们一块儿学习下Gradle高级知识:构建脚本,自定义任务,构建生命周期,解决依赖冲突,多项目构建等高阶技巧。java
- 在 project 根目录新建****.gradle 文件;
- 经过
apply from
引入该配置文件,而后使用rootProject.ext
引入相关属性.
//1.好比这里新建文件为config.gradle ext { versions = [ sdkMinVersion : 14, sdkTargetVersion : 26, ... ] depVersion = [ appCompatVersion : "26.+", recyclerViewVersion : "26.0.0-alpha1" ] deps = [ suport : [ appcompat : "com.android.support:appcompat-v7:${depVersion.appCompatVersion}", recyclerview: "com.android.support:recyclerview-v7:${depVersion.recyclerViewVersion}" ] ] } // 2. 引入已声明好的属性 apply from: 'config/config.gradle' android { def versions = rootProject.ext.versions compileSdkVersion versions.sdkCompileVersion buildToolsVersion versions.toolsBuildVersion ... } dependencies { def dependencies = rootProject.ext.deps compile dependencies.suport.appcompat } 复制代码
Error:Execution failed for task ':test:processDebugManifest'.> Manifest merger failed with multiple errors, see logs 复制代码
咱们通常的解决方案为:命令行输入gradlew processDebugManifest --stacktrace
.android
最后咱们在看个简单的单机执行任务 git
因为开发过程当中常常导入第三方jar包,一不当心就报jar包冲突这,这时咱们会执行 gradle app:dependencies
查看app重复依赖,而后在经过exclude剔除重复的jar。github
compile ('com.android.support:design:22.2.1') { exclude group: 'com.android.support' } 复制代码
其实当咱们点击后Gradle会去寻找当前目录下的 build.gradle 的文件,这个文件是 Gradle 的脚本文件,它里面定义了工程和工程拥有的全部任务等信息。而后执行相关task。下面咱们一块儿来一步步揭开它的神秘面纱吧。api
就像上面的截图同样,咱们知道,每个 Gradle 的项目都会包含一个或多个工程,每个工程又由一个或多个任务组成,一个任务表明了一个工做的最小单元,它能够是一次类的编译、打一个 JAR 包、生成一份 Javadoc 或者是向仓库中提交一次版本发布。bash
在任务中,我么能够利用
dependsOn
定义依赖关系,doFirst
、doLast
对现有任务加强。 咱们仍是使用 IDEA 开发工具打开以前的项目工程,把以前 build.gradle 文件中全部的内容所有删除,编写输入以下代码markdown
task hello { doLast { println 'Hello world!' } } task release() { doLast { println "I'm release task" } } // 添任务依赖关系 release.dependsOn hello //对现有的任务加强 // 法方一,在doFirst动做中添加 hello.doFirst { println 'Hello doFirst' } // 法方二 在doLast动做中添加 hello.doLast { println 'Hello doLast' } 复制代码
打开命令行端终,执行命令:gradle -q release
,输出结果以下:app
task myTask { ext.myProperty = "myValue" } task printTaskProperties { doLast { println myTask.myProperty } } 命令行执行 ➜ gradle -q printTaskProperties myValue 复制代码
固然咱们能够对现有任务进行配置:禁用或者重写。 首先咱们定义一个 myCopy 的任务,代码以下:maven
task myCopy(type: Copy) { from 'resources' into 'target' include('**/*.txt', '**/*.xml', '**/*.properties') } 复制代码
相似java有API文档,Gradle也有相似文档,Gradle 中不少其它经常使用的任务,小伙伴们能够点击查看, 若是咱们想重写 copy任务可经过overwrite属性为 true 来现以下所示:
task copy(type: Copy) task copy(overwrite: true) { doLast { println('overwrite the copy.') } } 命令行执行 > gradle -q copy overwrite the copy. 复制代码
最后咱们看下如何禁用某些任务。直接看代码吧
copy.enabled = false 复制代码
接下来咱们来自定义插件,有三种方式来编写
在咱们构建项目的 build.gradle 脚本中直接编写,这种方式的好处是插件会自动被编译加载到咱们的 classpath 中,可是它有很明显的局限性,就是除了在包括它的脚本外别的地方没法复用。
在咱们构建项目的rootProjectDir/buildSrc/src/main/groovy 目录下编写,Gradle 会自动编译到当前项目的 classpath 中,该项目下全部编译脚本均可以使用,可是除了当前项目以外的都没法复用。
以单独的工程方式编写,这个工程最终编译发布为一个 JAR 包,它能够在多个项目或不一样的团队中共享使用。
接下来咱们一步步把按照第三种方式写个Demo吧。
apply plugin: 'hello'
,里面像这样输入插件的全路径名字:implementation-class=org.gradle.HelloPlugin
- 继承自DefaultTask的,使用TaskAction进行标注,这样 Gradle 就会在任务执行的时候默认调用它
- 而后经过实现Plugin接口来实现自定义插件类,实现apply(Project project) 方法。
按照步骤,首先咱们新建MyTask.groovy文件,里面仅仅是简单声明了一个成员变量,而后打印。
class MyTask extends DefaultTask { String input = 'hello from MyTask' @TaskAction def greet() { println input } } 复制代码
而后咱们新建Hello.groovy文件.咱们向这个plugin添加了一个hello任务
,咱们知道gradle中能够配置参数好比:defaultConfig {} ndk {}
等,其实gradle是使用 extension objects来现实给插件传参,具体实现看下面代码的注释:
class Hello implements Plugin<Project> { @Override void apply(Project project) { // 向extension container保存para参数,并应用给HelloPluginExtension project.extensions.create("para", HelloPluginExtension) // 向project对象添加hello任务 project.task('hello',type:MyTask) { input = 'Hello Plugin input!' doLast { println "${project.para.first}${project.para.last}" } } } } 复制代码
build.gradle
中输入//使用 maven-publish 插件先发布到本地 apply plugin: 'maven-publish' publishing{ publications { mavenJava(MavenPublication) { from components.java groupId 'org.gradle' artifactId 'customPlugin' version '1.0-SNAPSHOT' } } repositories{ maven { // change to point to your repo, e.g. http://my.org/repo url "../repo" } } } 复制代码
点击publish任务,看到成功发布工程到本地仓库../repo中了。
Project.fileTree(java.util.Map)
建立,可使用过虑条件来包含或排除相关文件。// 指定目录建立文件树对象 FileTree tree = fileTree(dir: 'src/main') // 给文件树对象添加包含指定文件 tree.include '**/*.java' //andoid中使用文件树 implementation fileTree(include: ['*.jar'], dir: 'libs') 复制代码
注意 settings.gradle
引入的module才会参与编译include ':app', ':plugin_common', ':plugin_gallery'
,能够在跟guild.gradle
中统一设置公共行为;好比下图添加一个hello任务。
一个工程的路径为:以冒号(: 它表明了根工程)开始,再加上工程的名称。例如“:common”。 一个任务的路径为:工程路径加上任务名称,例如“:common:hello”. 好比:仅仅执行 gradle :plugin_common:hello