AndroidGradle最实用的指南
AndroidStudio目前已经成为Android开发人员的主流工具,而Gradle的原理,配置,使用仍然是很多android开发人员感到困惑的地方。网上虽然有很多相关文档,但是要么是只会用但是不知道gradle的原理,要么就是过于深究Gradle和Groovy,没能和具体的android使用场景结合,导致很多人看完云里雾里。本文只针对android开发人员,结合具体使用,捎带介绍一下Gradle和Groovy的本质,希望可以让更多的android开发人员不仅能知其然,更能知其所以然。
参考书籍:
实战Gradle
Android Gradle 权威指南
巧用Gradle构建Android应用
1. Gradle简介
2013 年,Google 发布了全新的 Android 开发 IDE————Android Studio,核心是 Google 新推出的 Gradle 编译环境。首先,我们要明白,Android Studio 使用 Gradle 构建工具,Eclipse 的 ADT 插件使用的是 Ant 构建工具。其次,要搞明白Android Studio 为什么使用 Gradle 构建工具。Gradle有什么特点呢?
- 采用了 Domain Specific Language(DSL 语言) 来描述和控制构建逻辑。
- 构建文件基于 Groovy,并且允许通过混合声明 DSL 元素和使用代码来控制 DSL 元素以控制自定义的构建逻辑。
- 支持 Maven 或者 Ivy 的依赖管理。
- 非常灵活。允许使用最好的实现,但是不会强制实现的方式。
- 插件可以提供自己的 DSL 和 API 以供构建文件使用。
- 良好的 API 工具供 IDE 集成。
由此可知,Gradle 之所以强大是因为继承了强大、灵活的 Ant 和 Maven 丰富的依赖管理,配置管理简单,脚本编写方便灵活,插件模块化。
2. AS中的Gradle文件
Gradle的优越性让它在很多地方都有应用,本文从Android的角度来分析和使用。
Android中的一个项目结构通常如下:
相关文件信息如下:
目录文件 | 定义 |
---|---|
.gradle | gradle项目产生文件(自动编译工具产生的文件) |
.idea | IDEA项目文件(开发工具产生的文件) |
app | 其中一个 module,复用父项目的设置,可与父项目拥有相同的配置文件 |
build | 自动构建时生成文件的地方 |
gradle | 自动完成 gradle 环境支持文件夹 |
.gitignore | git源码管理文件 |
build.gradle | gradle 项目自动编译的配置文件 |
gradle.properties | gradle 运行环境配置文件 |
gradlew | 自动完成 gradle 环境的 linux mac 脚本,配合 gradle 文件夹使用 |
gradlew.bat | 自动完成 gradle 环境的 windows 脚本,配合 gradle 文件夹使用 |
local.properties | Android SDK NDK 环境路径配置 |
*.iml | IDEA 项目文件 |
setting.gradle | gradle 项目的子项目包含文件 |
2.1 settings.gradle
为什么我没有从build.gradle开始介绍,而是从settings.gradle这个文件开始呢?是因为这个问价是Gradle的设置文件,用于初始化以及工程树的配置,位置放在根工程目录下。设置文件大多数的作用是为了配置子工程。在Gradle中多工程是通过工程树表示的,就相当于As中看到的Project和Moudle的概念一样。根工程相当于AS中的Project,一个根工程可以有很多子工程,也就是很多Moudle。
一个子工程只有在settings文件里配置了Gradle才会识别,才会在构建的时候被包含进去。具体使用如下:
//定义一个名为initMinshengGradleEnvironment的函数。该函数内部完成一些初始化操作 //比如创建特定的目录,设置特定的参数等 def initTKGradleEnvironment(){ println"initialize TK Gradle Environment ....." ......//干一些special的私活.... println"initialize TK Gradle Environment completes..." } //settings.gradle加载的时候,会执行initTKGradleEnvironment
initTKGradleEnvironment()
include ':voice'
include ':imagepicker' project(':imagepicker').projectDir = new File(rootDir, 'tk/imagepicker')
首先,这个文件中可以自己设置一些函数,如initTKGradleEnvironment(),这些函数会在gradle构建整个工程任务的时候执行,所以,可以在settings做一些初始化的工作。
其次,可以通过include函数,将子Project的名字(其文件夹名)包含进来 。这里要注意的是,如果像imagepicker'子工程指定了文件夹的目录,它的工程目录就是rootDir/tk/imagepicker;而像voice子工程这样没有指定相应的文件夹目录,默认目录会是其同级的目录,即Gradle会把当前与settings.gradle文件同级的voice目录作为voice子工程的工程目录。如果没有的话,会报错。
2.2 build.gradle
每个project都会有build文件,该文件是该project构建的入口,可以在这里针对该project进行设置,比如配置版本,需要哪些插件,依赖哪些库等。AS项目结构中有两个build文件。我们分别对其进行介绍。
2.2.1 app Moudle的build文件
Android Studio 自动创建的 module 默认生成的 build.gradle 文件,这个文件是开发中打交道最多的一个文件。
这个文件中包括apply plugin,android,greendao,repositories,dependencies等多个代码块。
android { compileSdkVersion project.ANDROID_BUILD_SDK_VERSION as int buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION defaultConfig { applicationId project.APPLICATION_ID versionCode project.VERSION_CODE as int versionName project.VERSION_NAME minSdkVersion project.ANDROID_BUILD_MIN_SDK_VERSION as int targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') //这里注意是双引号 compile "com.android.support:appcompat-v7:${SUPPORT_LIBRARY}" compile "com.android.support:design:${SUPPORT_LIBRARY}" compile "com.android.support:recyclerview-v7:${SUPPORT_LIBRARY}" compile "com.android.support:support-annotations:${SUPPORT_LIBRARY}" compile "com.android.support:cardview-v7:${SUPPORT_LIBRARY}" compile "com.android.support:support-v4:${SUPPORT_LIBRARY}" }
2.2.2 root Project的build文件
2.3 gradle.properties
配置全局的管理文件。用来配置 gradle 运行环境的文件,比如配置 gradle 运行模式,运行时 jvm 虚拟机的大小。
## Project-wide Gradle settings. # # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx1024m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Wed Mar 21 09:55:30 CST 2018 org.gradle.jvmargs=-Xmx1536m -Xmx4048m
properties其实是Java项目中的配置文件,不是Gradle独创的。又因为Gradle语法可以和Java进行混合使用,所以在Java项目上面使用properties文件的方式,在Gradle上面也可以使用。Gradle借用了这一点,所以内置了对gradle.properties的使用方式.
properties里面的数据格式采用键值对的方式,大概有以下几种写法:
1. key=value
2. key:value
3. key :value
4. # 作为注释
在Android Studio 中最好使用第一种写法,要不会有警告。
在实际开发中,一般大型的项目都是拆分进行模块化开发的,每个模块在合并的时候容易有冲突(比如版本冲突),或者需要改版本的时候比较麻烦,需要一个一个地方去改,这时候配置全局的 gradle.properties 文件就很有必要了。具体参考如下设置:
## Project-wide Gradle settings. # # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx1024m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Wed Mar 21 09:55:30 CST 2018 org.gradle.jvmargs=-Xmx1536m -Xmx4048m #添加ndk支持(按需添加) android.useDeprecatedNdk=true # 应用版本名称 VERSION_NAME=1.0.0 # 应用版本号 VERSION_CODE=100 # 支持库版本 SUPPORT_LIBRARY=24.2.1 # MIN_SDK_VERSION ANDROID_BUILD_MIN_SDK_VERSION=14 # TARGET_SDK_VERSION ANDROID_BUILD_TARGET_SDK_VERSION=24 # BUILD_SDK_VERSION ANDROID_BUILD_SDK_VERSION=24 # BUILD_TOOLS_VERSION ANDROID_BUILD_TOOLS_VERSION=24.0.3
2.4 local.properties
Android Studio 自动创建的工程中,IDE 自动配备了本地配置文件,并且设置了 sdk.dir 属性。也就是配置了 Android_Home 环境变量,所以 IDE 能够自动生成这个配置文件。一般情况都不用修改这个配置文件,除非你一定要重新制定一个 SDK 路径。