Android Studio中的Gradle的相关知识
最近发现自己对Android Studio中的Gradle的相关知识不是很熟悉了(汗),所以特地在周末查了资料重新熟悉了下。
构建工具
软件开发过程不仅仅是编写代码,还涉及到对项目的管理,比如:编译、签名、打包、依赖管理等一系列操作,为了复用以及自动运行这些操作,我们可以用代码来描述这些功能,而构建工具就是可以让我们用代码描述这些功能,并为这些功能性代码的运行提供环境支持的工具。
传统的构建工具有Make、Ant、Maven、Ivy等,而Android Studio中使用的是Gradle,所以接下来我们要对Android Studio中的Gradle的相关配置进行讲解。
Android Studio中Gradle,Gradle插件和BuildTools
Gradle,Gradle插件和BuildTools的区别
Gradle
Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,基于Groovy,build脚本使用Groovy编写,在android项目中可以自动帮我们完成项目的依赖,打包,签名,发布等一系列操作。
Gradle插件
Android Gradle Plugin作用是对Android项目提供Gradle构建环境,让开发者可以通过Gradle工具来运行构建。Gradle插件为Gradle的运行提供了环境支持。
BuildTools
Android构建的相关工具都在这里面,位于./sdk/build-tools/目录下,它提供了类似aapt、dx这样的工具,gradle则是使用这样的工具来完成相应的构建任务。
总结来说,Gradle插件为Gradle提供了运行环境,而BuildTools则是Gradle完成操作所需要借助的工具的集合。
指定Gradle的版本
更新Gradle也有两种方式:
- 通过选择File > Project Structure > Project来指定Gradle版本
- 在gradle/wrapper/gradle-wrapper.properties文件中编辑Gradle引用地址
指定Gradle插件的版本
安装Android Studio后就已经帮我安装了Gradle插件.但Gradle插件是独立于Android Studio运行的,所以它的更新也是与Android Studio分开的。
指定Gradle插件版本有两种方式:
- 在Android Studio中选择File > Project Structure > Project菜单
- 在顶层build.gradle中修改配置
下面的例子在build.gradle中设置Gradle版本为2.2.0:
1 | buildscript { |
注意:不应该动态指定版本号,如”com.android.tools.build:gradle:2.+”.这样做可能会导致意外的版本更新,并且会给解决版本差异带来困难。
如果指定的版本没有下载下来,那么项目在下次构建的时候Gradle会再去下载。或者你也可以点击Tools > Android > Sync Project with Gradle Files去下载。
指定BuildTools的版本
app目录下的build.gradle
1 | apply plugin: 'com.android.application' |
Gradle,Gradle插件和BuildTools的版本匹配
因为Gradle仍在发展,在不断更新,自然Gradle插件和BuildTools也需要不断更新版本才能提供对新版本Gradle的支持,它们之间存在着版本对应关系。
Android Studio中的Gradle的配置
设置Gradle的路径
use defalut gradle wrapper
当我们在setting下gradle下设置gradle选择“use defalut gradle wrapper(recommended)”时,as就会根据{project.dir}\gradle\wrapper\gradle-wrapper.properties文件中的配置去查找gradle。
我们用as构建android项目时,配置gradle时我们必须在{project.dir}\gradle\wrapper\gradle-wrapper.properties文件中配置gradle包。
1 | #Mon Sep 11 14:41:13 CST 2017 |
GRADLE_USER_HOME是我们配置的Gradle所在路径的环境变量。配置的时候可以是“用户主目录/.gradle/wrapper/dists/gradle-..*”或者as安装目录下的gradle目录。
这个配置的gradle如果在目录“用户主目录/.gradle/wrapper/dists/..”存在的话,as就不会去https://services.gradle.org/distributions/gradle-3.3-all.zip去下载了,as就会利用该目录下对应版本的gradle进行相应自动编译操作,如果该目录下不存在gradle的话as就会去站点根据gradle的版本去下载到“用户主目录/.gradle/wrapper/dists/gradle-3.3-all”目录下。
use local gradle distribution
当我们在setting下gradle下设置gradle,如果选择的是“use local gradle distribution”的话,表示用的是本地的gradle,一般情况下本地的gradle目录会选择as的主目录下的gradle目录。这个时候{project.dir}\gradle\wrapper\gradle-wrapper.properties文件中的配置就会失效,也就是说as不会去“用户主目录/.gradle/wrapper/dists/gradle-..*”中去查找gradle。
Offline work
前面的两个配置是查找构建项目所需要的gradle,而如何Offline work(离线模式)则是和gradle管理依赖有关,选择这个选项,开启离线模式后,Gradle将不会联网查找依赖,而是仅从本地缓存中查找,所以要慎重开启此选项。
补充:
Gradle下载的依赖包的缓存目录
下载的依赖保存在“用户主目录/.gradle/wrapper/dists/gradle-..*”或者as安装目录下的gradle目录。
配置用户环境变量的方法
打开终端输入 open .bash_profile,添加如下内容:
1 | GRADLE_HOME=“用户主目录/.gradle/wrapper/dists/gradle-*.*.*”或者as安装目录下的gradle目录 |
保存退出后,在终端输入:source .bash_profile更新配置。
给Gradle设置代理
Gradle下载依赖的时候,Gradle默认直连网络,即使Mac设置了全局代理也是一样。就算你给Android Studio设置了代理,它依旧会风轻云淡地直连那个你在中国一辈子也不可能连上的网站……
要让Gradle走代理,加快下载依赖包的速度,你需要给它进行单独的配置。
设置全局代理
通过命令行
socks
1 | gradle -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=1080 build |
http
1 | gradle -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080 build |
https
1 | gradlew -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8080 build |
通过配置gradle.properties
在.gradle目录中创建gradle.properties文件,.gradle目录默认在用户目录下(区别window/linux),如果你设置了环境变量GRADLE_USER_HOME=“地址”,那么就在这个地址下。
在gradle.properties加入如下内容:
socks
1 | systemProp.socksProxyHost=127.0.0.1 |
http
1 | systemProp.http.proxyHost=www.somehost.org |
https
1 | systemProp.https.proxyHost=www.somehost.org |
相同代理协议下,命令行方式中参数-Dxxx的xxx与gradle.properties中systemProp.xxx的xxx是一致的。所以,了解其中一种方式即可,需要时转为另一种方式也很简单
对单个项目设置代理
在项目根目录下gradle.properties 文件中,添加以上内容即可。
Android项目中Gradle相关文件说明
Android Studio中项目的文件目录结构图:
从上图中我们可以看到,与 Gradle 有关的文件基本上分为七种:
- app目录下的build.gradle (当然其他 module 下也有);
- 根目录下的gradle 文件夹;
- 根目录下的build.gradle ;
- 根目录下的settings.gradle ;
- 根目录下的gradle.properties ;
- 根目录下的local.properties ;
- 根目录下的gradlew和gradlew.bat ;
也许有人会说根目录下还有一个config.gradle文件呢,其实这是我自定义的 gradle文件,自定义Gradle文件会在下面中讲解,这里先搁置一下。好了,那么我们一个一个地来看看他们的作用吧。
app目录下的build.gradle
1 | apply plugin: 'com.android.application' |
第一句apply plugin:’com.android.application’主要用来申明这是一个Android程序。而dependencies用于引入依赖,这个相信大家都比较了解了。其他的配置比较简单都有注释,就不展开讲了。
CompileSdkVersion是告诉gradle用哪个SDK版本来编译,和运行时要求的版本号没有关系;使用任何新添加的API就需要使用对应Level的Android SDK。
buildToolsVersion是Android构建工具的版本,其中包括了打包工具aapt、dx等等。这个工具的目录位于..your_sdk_path/build-tools/XX.XX.XX,buildToolsVersion的版本需要>=CompileSdkVersion;高版本的build-tools可以构建低版本的android程序。例如:
1 | compileSdkVersion 18 |
minSdkVersion最低适用sdk版本,如果compileSdkVersion设置为可用的最新API,那么minSdkVersion则是应用可以运行的最低要求。minSdkVersion是Google Play商店用来判断用户设备是否可以安装某个应用的标志之一。
targetSdkVersion目标sdk版本,targetSdkVersion是Android系统提供前向兼容的主要手段。这是什么意思呢?随着Android系统的升级,某个系统的API或者模块的行为可能会发生改变,但是为了保证老APK的行为还是和以前兼容。只要APK的targetSdkVersion不变,即使这个APK安装在新Android系统上,其行为还是保持老的系统上的行为,这样就保证了系统对老应用的前向兼容性。关于相关的例子和原理,建议阅读:Android targetSdkVersion 原理。
minSdkVersion和targetSdkVersion与compileSdkVersion的另一个不同之处是它们会被包含进最终的APK文件中,如果你查看生成的AndroidManifest.xml 文件,你会看到类似下面这样的标签:
1 | <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="7" /> |
如果你在manifest文件中手工设置,你会发现Gradle在构建时会忽略它们(尽管其它构建系统可能会明确依赖它们)。
如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion
当然除了上面的配置之外,还有很多配置也常常写入到app/build.gradle 中。我们慢慢往下看。
- 签名配置:
1 | signingConfigs { |
使用时只要在buildTypes的release中加一句signingConfig signingConfigs.release就好了。
如果你觉得把密钥密码和别名密码放在 app/build.gradle 里不安全,那么可以把相关密码放到不加入版本控制系统的 gradle.properties 文件:
1 | KEYSTORE_PASSWORD=xxxxxxxxxx |
对应的 signingConfigs 配置:
1 | signingConfigs { |
- Java编译版本配置:
1 | compileOptions { // java 版本 |
这里需要注意下,如果Java编译版本为1.8的话,另外在defaultConfig 里要配置Jack编译器:
1 | jackOptions { |
- Lint检查配置:
1 | lintOptions { |
- 多渠道信息配置:
1 | productFlavors { |
整个app/build.gradle文件配置如下所示:
1 | apply plugin: 'com.android.application' |
再多嘴一句,有了以上的build.gradle配置之后,如果想使用Gradle多渠道打包,需要在AndroidManifest.xml中申明:
1 | <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}" /> |
最后使用命令 gradlew assembleRelease 打包即可。
根目录下的gradle文件夹
gradle文件夹中主要是gradle-wrapper.properties文件比较重要,主要用来声明Gradle目录以及Gradle下载路径等:
1 | distributionBase=GRADLE_USER_HOME |
里面参数的具体的意义,前面已经讲解过了,这里就不再复述了。
根目录下的build.gradle
根目录下的 build.gradle主要作用就是定义项目中公共属性,比如有依赖的总仓库、Gradle插件的版本等:
1 | buildscript { |
根目录下的setting.gradle
这个文件是全局的项目配置文件,里面主要声明一些需要加入gradle的module,一些module被主module依赖后,会在这里进行声明。
1 | include ':app',':brave' |
通过上述的setting.gradle,我们可以知道整个项目中包含了app和brave两个module。
根目录下的gradle.properties
配置gradle运行环境的文件,比如配置gradle运行模式,运行时jvm虚拟机的大小,设置gradle的代理等。
根目录下的local.properties
local.properties文件在Android Studio中是用来配置SDK目录的,也可以在文件中配置一些本地化的变量。这个文件不会被提交到版本控制中。
为了安全起见签名文件不可以放在项目中,那么可能每个开发人员的存放地方不同,这种情况下就可以使用local.properties来配置路径然后在app目录下的build.gradle中引用。
1 | ## This file is automatically generated by Android Studio. |
在build.gradle中引用:
1 | signingConfigs { |
根目录下的gradlew和gradlew.bat
其实Gradlew只是一个Gradle的封装,是给Unix用户用的。这个脚本的最前面的注释也说明了这个功能:
1 | ############################################################################## |
同样的,gradlew.bat也是一个Gradle的封装,是给Windows用户用的。
1 | @rem ########################################################################## |
这两个文件的作用就是,任何机器都可以执行gradle构建任务,即使没有装gradle,例如:
1 | ./gradlew assemble |
如果运行时,发现系统没有对应版本的gradle,会通过gradle-wrapper.jar下载gradle-wrapper.properties中指定的gradle版本。这样的话,任何人获取代码后,不用安装gradle,就可以构建工程。
gradle-wrapper.properties文件中指定的版本,就是运行gradle wrapper命令时的gradle版本。
当然,也可以手动指定别的版本,在根目录下build.gradle文件中添加:
1 | task wrapper(type: Wrapper) { |
再运行gradle wrapper。
这两个文件最重要的运用就是:
- 在公司内统一gradle版本
- 把gradle-wrapper.properties里面的下载gradle的链接切换到公司的公共空间上,那么下载和安装gradle的时间就可以忽略不计了。
自定义Gradle文件
在上面我们留了一个悬念,就是如何添加我们自定义的Gradle文件。接下来我们就动手来实践一下。在项目根目录下创建文件config.gradle。然后在根目录下的build.gradle开头添加一句apply from: “config.gradle”:
1 | apply from: "config.gradle" |
这句话就代表着把config.gradle添加进来了。然后我们可以在config.gradle中申明一些配置:
1 | ext { |
最后在app/build.gradle中去使用:
1 | android { |
从上面可以看到,我们把一些固定的配置“拎”出来放到config.gradle 中,这样以后直接更改config.gradle就行了,方便多人协作开发。
Android Studio中的Gradle工具窗口
可以通过View->Tool windows->Gradle打开,也可以从右侧纵向标签页点击打开。
参考链接
Android Gradle和Gradle插件区别
Gradle构建工具与Android对应关系
AndroidStudio gradle配置
Mac下AndroidStudio中手动配置Gradle
IDEA及Gradle使用总结
Gradle中文教程系列-跟我学Gradle-14.1:IDEA中Gradle插件的使用
给ANDROID 初学者的GRADLE知识普及
ANDROID 开发你需要了解的GRADLE配置
关于Android Studio里的Gradle,你所需要知道的都在这里了
AndroidStudio gradle安装配置详解-透过现象看本质
Android local.properties配置文件的使用
使用Gradle构建Android程序(再仔细看看)
请问android studio创建的工程目录下的gradlew文件有什么作用?gradlew 和 gradle 有什么区别?
Gradle 完整指南(Android) //待读
Android Studio中Gradle使用详解 //待读
Android studio Gradle的介绍和部分问题小结//待读
Android Studio中Gradle使用详解//待读
Android中Gradle详细实用指南//待读
Android Studio Gradle使用笔记//待读
Gradle Android插件用户指南翻译
Android Plugin DSL Reference
深入理解Android(一):Gradle详解
Groovy Tip 12 Range的用法
Groovy基础——Closure(闭包)详解
Gradle User Guide
AndroidStudio配置构建
Android Plugin DSL Reference
Gradle-中文用户组一款简洁而优雅的构建工具
Gradle全局变量设置、自定义BuildConfig
Gradle配置全局变量
利用 Android Studio 和 Gradle 打包多版本APK( applicationIdSuffix)
application android:debuggable=”false” 有什么用?
android lint选项含义
Gradle lint 配置
解决AndroidStudio导入项目在 Building gradle project info 一直卡住
加速Android Studio/Gradle构建
加快gradle的编译速度总结-亲身经历
解决传说中的 Android 65k 问题
Android Studio 错误 Duplicate files copied in APK META-INF/LICENSE.txt
Duplicate files copied in APK META-INF/license.txt
NDK SO 库开发与使用中的 ABI 构架选择
studio android.useDeprecatedNdk=true解决ndk提示版本低不能自动编译jni