内容简介:我们一般的解决方案为:命令行输入其实当我们点击后Gradle会去寻找当前目录下的 build.gradle 的文件,这个文件是 Gradle 的脚本文件,它里面定义了工程和工程拥有的所有任务等信息。然后执行相关task。下面我们一起来一步步揭开它的神秘面纱吧。
上篇,我们已经介绍了Gradle的基本语法 ,接下来让我们一起学习下Gradle高级知识:构建脚本,自定义任务,构建生命周期,解决依赖冲突,多项目构建等高阶技巧。
接下来,我们先看下gradle的几个个简单应用
- 由于项目越来越大,组件化盛行,有时我们不得不多module统一版本管理。一般做法是:
- 在 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 .
-
最后我们在看个简单的单机执行任务
-
由于开发过程中经常导入第三方jar包,一不小心就报jar包冲突这,这时我们会执行
gradle app:dependencies查看app重复依赖,然后在通过exclude剔除重复的jar。
compile ('com.android.support:design:22.2.1')
{
exclude group: 'com.android.support'
}
复制代码
其实当我们点击后Gradle会去寻找当前目录下的 build.gradle 的文件,这个文件是 Gradle 的脚本文件,它里面定义了工程和工程拥有的所有任务等信息。然后执行相关task。下面我们一起来一步步揭开它的神秘面纱吧。
Gradle 中的工程( Project )和任务( Task )
就像上面的截图一样,我们知道,每一个 Gradle 的项目都会包含一个或多个工程,每一个工程又由一个或多个任务组成,一个任务代表了一个工作的最小单元,它可以是一次类的编译、打一个 JAR 包、生成一份 Javadoc 或者是向仓库中提交一次版本发布。
任务的定义和使用
在任务中,我么可以利用 dependsOn 定义依赖关系, doFirst 、 doLast 对现有任务增强。 我们还是使用 IDEA 开发 工具 打开之前的项目工程,把之前 build.gradle 文件中所有的内容全部删除,编写输入如下代码
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 ,输出结果如下:
另外我们还可以为任务设置属性,主要通过 ext.myProperty 来初始化值,如下所示
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties {
doLast {
println myTask.myProperty
}
}
命令行执行 ➜ gradle -q printTaskProperties
myValue
复制代码
当然我们可以对现有任务进行配置:禁用或者重写。 首先我们定义一个 myCopy 的任务,代码如下:
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吧。
首先使用IDEA新建gradle 工程选择groovy(跟上面一样就不细说了),然后按照下面截图新建src/main/groovy/你的包名,接着在resources 目录下建立 META-INF/gradle-plugins 文件夹,在其中新建 hello.properties 文件,敲黑板注意此处文件名,就是以后使用时要用的名字。此处是hello,所以我们得按照这样引入 apply plugin: 'hello' ,里面像这样输入插件的全路径名字: implementation-class=org.gradle.HelloPlugin
接下来分 2 步编写代码:
- 继承自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中了。
最后用 IDEA 开发工具新创建一个 Gradle 工程来验证我们的插件。看到右侧gradle任务中多了我们添加的hello任务,点击查看成功输出了Hello world。
补充及常见问题
文件树是有层级结构的文件集合,一个文件树它可以代表一个目录结构或一 ZIP 压缩包中的内容结构。使用 Project.fileTree(java.util.Map) 创建,可以使用过虑条件来包含或排除相关文件。
// 指定目录创建文件树对象 FileTree tree = fileTree(dir: 'src/main') // 给文件树对象添加包含指定文件 tree.include '**/*.java' //andoid中使用文件树 implementation fileTree(include: ['*.jar'], dir: 'libs') 复制代码
多module的编译配置
注意 settings.gradle 引入的module才会参与编译 include ':app', ':plugin_common', ':plugin_gallery' ,可以在跟g uild.gradle 中统一设置公共行为;比如下图添加一个hello任务。
一个工程的路径为:以冒号(: 它代表了根工程)开始,再加上工程的名称。例如“:common”。 一个任务的路径为:工程路径加上任务名称,例如“:common:hello”. 比如:仅仅执行 gradle :plugin_common:hello
以上所述就是小编给大家介绍的《Android Gradle Groovy自动化构建进阶篇》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 构建自动化
- 自动化构建工具 Gradle 4.5 RC1 发布,改进构建缓存
- 一种自动化的信息管理构建系统
- 利用fastlane进行项目的自动化构建
- Gradle 6.3 发布,项目自动化构建工具
- CMake 3.8.2 发布,自动化构建系统
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
scikit learn机器学习
黄永昌 / 机械工业出版社 / 2018-3-1 / CNY 59.00
本书通过通俗易懂的语言、丰富的图示和生动的实例,拨开了笼罩在机器学习上方复杂的数学“乌云”,让读者以较低的代价和门槛轻松入门机器学习。本书共分为11章,主要介绍了在Python环境下学习scikit-learn机器学习框架的相关知识。本书涵盖的主要内容有机器学习概述、Python机器学习软件包、机器学习理论基础、k-近邻算法、线性回归算法、逻辑回归算法、决策树、支持向量机、朴素贝叶斯算法、PCA ......一起来看看 《scikit learn机器学习》 这本书的介绍吧!