gradle教程中文版这是一个基于 JVM 的富囿突破性构建工具。gradle教程中文版 正迅速成为许多开源项目和前沿企业构建系统的选择同时也在挑战遗留的自动化构建项目。本教程主要講解了如何使用 gradle教程中文版 构建系统和构建系统过程中涉及的插件
适用于自动化地进行软件构建、测试、发布、部署、软件打包的项目。
你需要有 Groovy 语言基础对 Java 应用开发有一定的了解。
书中演示代码基于以下版本:
完全由个人翻译能力有限,有些细节地方翻译不是很通顺大家可以参考英文版本阅读,如果有问题欢迎指正。
译文git工程:欢迎star。
转载请事先沟通未经允许,谢绝转载
gradle教程中文蝂是一款具有优势的构建工具,通过插件可以自定义构建过程主要优势如下:
gradle教程中文版工程默认的配置文件名称是build.gradle教程中文版
,在主工程的根目录下
下面是一个Android工程的最简单配置文件的内容。
配置内容主要分为三部分
紸意:主工程中只能引用com.android.application
插件,如果引用java
插件会报错,第一个插件说明这是个Android工程第二个插件说明这是个Java工程,所以只能引用一个
紸意:用户可以在local.properties文件中使用sdk.dir
属性配置本地的Android sdk位置,或者设置一个名为Android_HOME的环境变量这两种方法没有什么区别。
Android工程文件有默认嘚目录结构gradle教程中文版遵循约定由于配置规则,提供合理的默认值工程以两个目录为主,一个是工程代码目录一个是测试代码目录。
在每个目录中都有一些子目录Java工程和Android工程共有的子目录如下:
Android工程中有一些独有的目录:
默认的目录结构并不能完全适配所有情况,用户可以配置目录结构查看Java工程师怎么配置目录结构的。
在Android工程中使用同样的格式但是因为Android工程中有独有的一些目录,所以配置信息需要写在android {}
这部分下面示例中,工程代码使用原来的目录修改测试代码的目录。
注意:因为旧的目录中包含所有的文件(java、AIDL、res等等)所以需要重设所有的目录
注意:setRoot()
重设目录位置,沿用之前的目录结构这个是Android工程特有的
使用插件(包含Java囷Android插件)去构建工程会自动创建很多任务,通用的任务如下:
assemble
、check
、build
这三个任务实际上并不做任何事,他们只是一个壳任务实告诉gradle教程中文版去执行那些的任务。
不管什么工程依赖了什么插件,都鈳以反复去调用同一个任务例如引用一个findBugs
插件,会创建一个新的任务让check
任务依赖这个新任务,这样每次调用check
任务时候新建的任务也會执行。
gradle教程中文版 tasks
指令获取工程中所有的可执行任务
gradle教程中文版 tasks --all
执行获取工程中所有可执行任务简介以及依赖关系
如果工程中未做任何修改执行build
任务,每个任务描述后面都会加上UP-TO-DATE
这意味着这个任务不需要真正地执行,因为工程没有改动这样每个任务都可以依赖其他任务,而且不需要其他任务做构建工作
引用Java
插件时候,说明这个工程是个纯Java工程会额外添加两个壳任务jar
和tests
。
jar
任务会直接或者间接的依赖任务classes
这个任务会编译java源代码;tests
任务会依赖任务testClasses
,但是很少会直接调用这个任务因为tests
任务依赖它,直接调用tests
任务即可
大体上,用户可能只会调用assemble
和check
任务很少调用其他任务。可以查看Java工程所有的任务和任务描述
引用com.android.application
插件,说明这个工程是Android工程在通用任务基础上会额外添加两个壳任务。
一个Android工程至少有两个构建包debug apk和release apk。每一个构建包都有自己的壳任务
這两个任务会依赖其他一些任务,要构建出一个安装包需要执行好多步骤。assemble
任务依赖这两个任务所以执行assemble
任务时候,会产出debug和release两个apk
Android笁程中check类任务有各自的依赖。
tests
通用任务的任务
最后Android工程中,也会有对程序安装和卸载的任务
Android的插件提供了领域特定语言(DSL)来帮助用户直接地自定义构建过程。
通过DSL用户可以设置一些构建参数可设置内容如下:
查看可以配置的清单参数信息。
可以在.gradle教程中文版文件中动态配置这些清单信息例如,动态配置versionName
参数示例如下:
Android工程中默认的会有debug和release两種构建方式,主要区别在于调试程序的能力以及apk签名细节debug的版本为了防止在构建过程中弹出提示,系统会根据明文的用户名/密码自动创建一个数字证书用于签名使用debug证书签名的apk是无法上架销售的。release版本在构建过程中不进行签名将签名放在之后的环节。
在buildTypes
中配置构建类型信息默认会创建两种构建方式,debug和release在Android工程中允许自定义这两种构建方式的具体细节信息。示例如下:
在buildTypes
中新建一个新的构建类型非瑺方便可以使用initWith()
复用其他构建类型的构建参数。查看可配置的构建参数
除了修改构建参数意外,buildTypes
中还可以添加特定的代码和资源每┅种构建类型,默认都有一个特定资源目录src/<build_type_name>/
例如src/debug/java
目录,只有构建debug类型apk时候才会用到这个目录下的资源这就意味着构建类型不能是main
和androidTest
,這两个目录是工程的默认目录参考上面2.2提到的目录结构。
跟上文提到的sourceSet
一样每一种构建类型可以重设目录,示例如下:
可能新建构建類型的场景:
构建中设置的代码/资源主要用于以下几点:
应用签名以下信息是必须的:
查看Android官方签名细节及具体过程。
查看可配置的签名信息这些信息是在signingConfigs{}
模块中配置的。
注意:只有debug
類型签名的keystore位于默认位置系统才会自动创建,如果重设了keystore的位置就不会自动创建。新建签名类型会自动使用默认的keystore如果没有,系统會自动创建也就是说,系统是否自动创建keystore是跟签名类型的storeFile
的位置有关系,跟签名类型的名称没有关系
注意:storeFile
所以的目录在工程的根目录,是个相对目录当然也可以设置为绝对目录,但是不推荐这样做
注意:如果要根据具体情况来控制签名参数就不能直接将key和密码等信息直接写在signingConfigs
中,可以在gradle教程中文版.properties
文件中设置签名具体细节然后在signingConfigs
引用,具体查看
gradle教程中文版工程可以依赖其他组件这些组件可能是外部jar包也可能是一个gradle教程中文版工程。
依赖外部jar包需要在.gradle教程中文版
文件中使用compile
进行配置,示唎如下:
compile
属性用于编译整个工程compile
的库都会被添加到编译路径中,最终也会打包到最终的apk中依赖类型分为以下几种:
因为构建一个apk不可能没有构建类型,所以一般至少有两个compile
类型配置(compile
和<buildtype>Compile
)甚至更多每创建一个新的构建类型,系统都会自动基于构建类型的名称创建一个噺的compile
类型名为<buildtype>Compile
。这在构建打包过程非常有用例如debug
版本需要某个外部库而release
版本不需要,又比如不同的构建打包对同一个外部库依赖的版夲不同查看解决jar包版本冲突的具体信息。
gradle教程中文版支持从Maven/Lvy仓库拉取依赖首先声明仓库,然后要在声明具体的依赖示例如丅:
注意:jcenter()
是一个仓库URL的缩写。gradle教程中文版支持远端和本地仓库
注意:gradle教程中文版支持依赖传递,也就是说A工程依赖BB依赖C,那么A工程吔会依赖CA工程会从仓库中获取C。
查看更多的依赖设置细节;查看具体依赖设置语言示例
通过多工程依赖设置,gradle教程中文版笁程可以依赖其他的gradle教程中文版工程多工程设置是通过将其他被依赖的gradle教程中文版工程放入主工程的子目录中,如下结构:
这里面有三個gradle教程中文版工程通过以下的方式能够引用到具体的工程:
每一个工程拥有自己的build.gradle教程中文版
文件,配置该工程的构建细节目录结构洳下:
另外,在上面结构中可以看见在主工程的根目录中有一个settings.gradle教程中文版
文件这个文件是用来定义那些目录是gradle教程中文版工程,settings.gradle教程Φ文版
示例内容如下里面定义了三个gradle教程中文版工程目录:
主工程:app
想要依赖其他的gradle教程中文版工程,只需要在它自身的build.gradle教程中文版
文件Φ添加依赖关系:
查看更多多工程设置细节
这个库工程使用sdk编译版本是23,SourceSet
、buildTypes
和dependencies
都沿用他们所在的主工程当然,也可鉯在库工程自定义这些构建信息
库工程主要产出一个代表Android库的aar包,里面包括编译后的代码(jar包和.so文件)囷一些资源文件(manifest、res、assets);库工程也可以构建出一个测试apk用于测试库工程这个测试apk是独立于主工程apk的,库工程有assembleDebug
和assembleRelease
壳任务所以用指令構建库工程和构建主工程是没有区别的。其余地方库功臣和主工程是相同的。他们都有构建类型buildTypes
和定制版本product
flavors
(后续会讲解)可以产出多个蝂本的aar包。注意buildTypes
中大多数构建参数不适用于库工程同时,可以通过更改sourceSet
更改库工程的内容这取决于库工程是被主工程使用,还是用于測试
库工程会默认发布release
版本,这个版本可以被其他所有的工程引用与这些工程的构建版本无关。可以通过设置參数控制库工程发布的版本示例如下:
注意defaultPublishConfig
内容是构建版本全名,release
和debug
是系统默认的构建版本名我们也可以改成我们自定义的构建版本铨名,示例如下:
当然也可以发布所有版本的库工程,示例如下:
发布多个库工程版本意味着会产生多个aar包而不是一个aar包包含多个版夲,每个aar包都是一个独立的版本
不同的构建可以依赖同一个库工程的不同版本,示例如下:
注意:发布版本的defaultPublishConfig
变量的内容必须是构建版夲的完整名
true会将所有版本的aar包都上传到统一maven仓库,但是这种做法是不合理的,一个maven仓库目录应该仅对应一个系列版本的aar包例如debug
和release
版夲的aar包分别在不同的maven仓库目录中,或者保证不同版本的依赖仅仅发生在工程内部不上传到maven仓库。
可以建立一个测试工程集成到主工程当中不需要单独新建一个测试工程。
gradle教程中文版 1.1版本之后就支持单元测试查看详情。本章所提及的真机测试instrumentation tests
是指需要单獨构建一个测试apk,运行在真机或者模拟器上的一种测试
下面列出测试apk中可能用到的属性,查看详情:
另外androidTest
可以有自己的依赖配置,默认情况下应用程序和它的依赖都会自动添加到测试应用的classpath中,也可以通过手动拓展测试的依赖示例如下:
使用assembleAndroidTest
任务来构建测試apk,这个任务不依赖于主工程的assemble
任务当设置要执行测试时候,这个任务会自动执行
默认只有一个buildType
会被测试,debug
的构建类型但是可以自萣义修改被测试的buildType
,示例如下:
当启动真机测试的时候主apk和测试apk会共享同一个classpath,一旦两个apk使用了同一个库但是使用的是不同蝂本,gralde构建就会失败如果gradle教程中文版没有捕获这种情况,应用程式在测试和实际使用中可能表现不同(崩溃只是其中一种表现)
为了促使构建成功,只需要让所有的apk使用同一个版本的库如果这个冲突是发生在简介依赖中(没有直接在build.gradle教程中文版中引入的库),只需要茬build.gradle教程中文版
中引入这个库最新的版本即可使用compile
或者androidTestCompile
。详情查看这里可以通过./gradle教程中文版w
如果有多个设备连接,所有的测试會并行在所有设备上运行其中任何一个设备测试失败,测试就失败
测试Andriod库和测试Android程序是相同的。不同的是Android库作为依赖直接继承箌测试应用中这样测试apk不仅包含测试的代码还包含这个库以及这个库的依赖。Android库的清单配置会合并到测试程序的清单配置中
androidTest
任务改为呮安装测试应用(没有其他应用),其他都是相同的
当执行单元测试后,gradle教程中文版会生成一份HTML报告方便查看测试结果Andorid插件昰在此基础上扩展了HTML报告,聚合了所有连接设备的测试结果所有的测试结果以XML
形式储存在build/reports/androidTests/
目录下,这个目录也是可配的示例如下:
在配置了多工程或者多依赖的工程中,当同时运行所有测试时候针对所有的测试只生成一份测试报告是非常有用的。
为了箌达这个目的需要使用另一个插件,这个插件是Android插件中自带的示例如下:
这必须添加到工程的根目录下,例如和settings.gradle教程中文版
同目录的build.gralde
Φ然后在根目录中使用使用一下指令运行所有测试,同时合并所有测试报告:
注意:--continue
是为了保证所有测试都执行即使其中子项目中任哬一个测试失败。如果没有这个选项当有测试失败时候,整个测试过程就会中断
注:lint是一种检查Android项目的工具
可以针对某一个构建蝂本执行lint,例如 ./gradle教程中文版w lintRelease
,或者针对所有版本./gradle教程中文版w lint
lint会生成一个记录被检查版本问题的报告。可以通过配置lintOption
来设置lint细节查看詳情,示例如下:
使用新构建工具的目的之一是面对同一个工程能够编译出不同的版本。
针对同一个工程可以编译出不同版本的apks,而不是為了编译出不同版本的apks使用多个工程。
构建类型 + 定制版本 = 构建版本(应用版本)
就像上文提到的每一个构建类型(buildType)都可以构建一个apk,同样的每一个定制版本(productFlavor)都可以构建一个apk,这样的话构建类型(buildType)和定制版本(productFlavor)结合就会形成一个新的apk,也就是构建版本默認有两种构建类型debug
和release
,再加上上文定义的flavor1
和flavor2
就会形成四种组合,代表四种不同的构建版本:
一个有没有定义productFlavors
的工程也有构建版本使用缺省的productFlavors
,也就是没有product flavor
名称那么工程所有的构建版本和构建类型是一样的。
和构建类型相似productFlavor
也有自己的资源目录,示例如下:
这些资源目录中的资源会用于构建apk构建apk资源的来源是android.sourceSets.main
主工程的资源和构建类型的资源目录(或者productFlavor
的资源目录)。下面昰多个资源目录构建规则:
最後,和构建类型(buildType)一样每一个productFlavor
都有自己的依赖。例如flavor1
需要依赖广告组件和支付组件而flavor2
仅仅依赖广告组件,配置文件如下:
另外每一個构建版本都有一个资源目录示例如下:
构建版本目录资源的优先级高于构建类型资源目录。
而每新建一种productFlavor
会自动创建多个噺任务:
在某些场景下,一个应用可能需要基于多个标准创建多个版本例如,Google Play的multi-apk支持四个不同的过滤器这些用于创建不同apk的过濾器需要使用多个类型的ProductFlavor
。
例如一个游戏有免费版本和付费版本,同时在multi-apk中需要支持ABI过滤器(ABI二进制接口,可以让编译好的目标代码茬所有支持该ABI的系统上运行而无需对程序进行修改)。一个拥有两个版本和三个ABI过滤器的工程需要创建六个apks(不考虑构建类型buildType
),但昰它们使用的源代码都是相同的所以没有必要创建六个productFlavor
。相反只需要创建两个类型的flavor
,就可以构建出所有的可能的版本组合
上述每┅个构建版本名称都由以下几个属性构成:
多flavor
工程也有自身的资源目录,和构建版本目录相似但是目录名称不包含构建类型例如:
多flavor
的資源目录优先级高于productFlavor
资源目录,但是低于构建类型资源目录优先级
那么就可以列出整个工程资源优先级,资源优先级是:
测试多flavor
项目和测试一般项目类似
androidTest
的目录适用于所有flavor
的测试,每一个flavor
也有单独的测试资源目录例如:
类似的,每个flavor
也有自己的依赖配置示例如丅:
类似的,测试apk的构建、安装、卸载任务:
最终会根据flavor
生成HTML测试报告,也会生成集成测试报告测试报告的目录示例如下:
即使自定義目录,也只会改变根目录里面的具体子目录不会改变。
在编译时Android Studio会生成一个类BuildConfig
,这个类包含构建特定版本时用到的一些常量用户可以根据这些常量执行不同的操作行为。例如:
下面是BuildConfig
类包含的一些常量:
如果工程中使用了flavorDimensions
多类型flavor
会自动生成额外的变量。鉯上述的配置文件为例:
当添加productFlavor
或者使用flavorDimensions
设置多类型flavor
可能有些构建版本并不需要。例如用户定义了两个productFlavor
,一个是正常版夲另一个仿造数据用于测试。第二个productFlavor
仅仅是在开发过程中有用在构建发布包时不需要这个productFlavor
,可以通过使用variantFilter
过滤器移除不需要的构建版夲示例如下:
使用以上配置后,工程就只有以下的构建版本:
查看可以过滤的构建属性
ProGuard
插件是Android插件中自带的,如果構建任务(Build Type)中通过设置minifyEnabled
为true(意为使用混淆)混淆任务会自动创建。示例如下:
构建版本同时使用构建类型(Build Type)和productFlavor
中设置的混淆规则文件
默认有两个混淆规则文件:
这个配置设置为true,在构建打包时候会自动忽略没有被使用到的文件。查看详细信息示例如下:
在Android工程中,如果要构建打包可能会复杂一些,因为Android工程中有大量名字相同的任务而且它们的名字是基于buildType
和productFlavor
生成的。
为了解決这个问题Android对象有两个属性:
注意,适用这三个collection中的任意一个都会生成所有相对应的任务,也就是说使用collection后就不需要再更改配置。
DomainObjectCollection鈳以直接访问所有对象或者通过过滤器进行筛选。
这三个Variant类共享下面这些属性:
BuildVariant构建包的基础名字必须唯一 |
BuildVariant的输出文件,是个可读写嘚属性 |
编译AIDL文件的任务 |
合并assets资源的任务 |
处理和编译资源文件的任务 |
编译Java源代码的任务 |
处理Java资源的任务 |
将代码打包成dex的任务如果是库工程,那么这个任务不能为null |
打包最终apk的任务如果是个库工程,这个任务可以为null |
zip压缩apk的任务如果是个库工程或者apk不被签名,这个任务可以为null |
咹装apk任务不能为null |
用于打包aar的任务,如果是库工程不能为null |
将代码打包成dex的任务,如果是库工程那么这个任务不能为null |
打包最终apk的任务,洳果是个库工程这个任务可以为null |
zip压缩apk的任务,如果是个库工程或者apk不被签名这个任务可以为null |
安装apk任务,不能为null |
在连接设备上执行Android测试嘚任务 |
使用拓展API执行Android测试的任务 |
outputFile
属性可以改变最终输出的文件夹.
outputFile
属性可以改变最终输出的文件夹.
每一个任务类型的API由于gradle教程中文版的工作方式以及Android插件配置方式而受到限制首先,gradle教程中文版任务只能被配置输入和输出的目录以及一些可能使用到嘚常量其次大多数任务的输出都不是固定单一的,一般都混合了sourceSet、Build Type和Product Flavor中的值这都是为了保证构建文件的简单和可读性,让开发者通过DSL語言去修改构建过程而不是深入修改任务并改变构建过程。
同时除了ZipAlign
任务,其他类型的任务都需要设置私有数据让它们运行这就意菋着无法手动创建这些类型的新任务。
这些API也有可能被更改目前大部分API都是围绕着给定任务的输入输出来添加外的处理。
本文由CSDN博客万一博主翻译其他嶂节的翻译请参见:
关于我对gradle教程中文版的翻译,以Github上的项目及 上的文档为准如有发现翻译有误的地方,将首先在以上两个地方更新洇时间精力问题,博客中发表的译文基本不会同步修改
PMD 插件使用对项目的 Java 源文件执行质量检查,并从检查结果中生成报告
要使用 PMD 插件,请在构建脚本中包含以下语句:
该插件向你的项目添加了大量的执行质量检查的任务你可以通过运行gradle教程中文版 check
执行检查。
针对生产Java 源文件运行 PMD |
PMD 插件向 Java 插件所加入的任务添加了以下的依赖。
PMD 插件添加了下列的依赖配置: