相信现在已经很少有公司android开发还用着Eclipse了吧,绝大部分都已经跟上潮流换上了Android Studio,AS默认使用Gradle作为项目构建工具。Gradle非常强大,可以方便我们做很多事情,例如:
(1)方便我们复用代码和资源
(2)方便我们使用相同的代码和资源构建出不同的应用
(3)方便我们配置项目构建流程,甚至是加入自定义逻辑
默认情况下build.gradle是这个样子的:
apply plugin: 'com.android.application'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
android {
compileSdkVersion 23
buildToolsVersion "23.1.0"
}
apply plugin
apply plugin声明插件,其实可以理解为gradle构建的项目类型。android常用的有:
- com.android.application:表示构建android应用,即最终build输出apk
- com.android.library:表示构建一个android库,最终输出aar格式文件
当项目业务越来越多,越来越繁杂时后,为了提高开发效率,通常会对project按业务拆分,单独业务拆分为一个子库,或者底层通用框架和工具拆分为单独的子库,最终利用一个空项目作为壳,将其他子库直接或者间接依赖进来打包成apk。这里,壳的build.gradle就得声明为’com.android.application’,而其他子库均以aar形式依赖进来,也就是说其他子库的build.gradle都是apply plugin: ‘com.android.library’。如果想要生成可安装的apk文件,必须得执行壳gradle的build task才行。
buildscript
buildscript中主要声明gradle工具build时自身需要的配置,而不是代码编译的配置,通常包括依赖仓库repositories以及具体的依赖dependencies。repositories既可以是远程仓库,也可以配置本地的仓库。
allprojects、subprojects
不同于buildscript,allprojects是对当前工程及其子工程进行配置,subproject是对当前工程所有子工程进行配置,通常配置项目依赖的所在仓库,可以为多个。
dependencies
配置项目具体的依赖,可以是仓库中的第三方库也可以是本地android library源码,还可以是本地jar包等。例如:
dependencies {
compile "com.android.support:recyclerview-v7:23.0.0"
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':libraries:lib2')
}
另外,在配置dependencies时也可以根据build type、product flavor或者build variant对具体的build类型进行依赖配置。例如上面代码中的releaseCompile和debugCompile分别只对release和debug类型build有效。
android
顾名思义,android{}是用来配置android编译阶段参数的,其中compileSdkVersion和buildtoolsVersion是必须配置的,其他常用的还有以下配置:
- defaultConfig
应用的默认配置,包括应用的唯一标识,可安装应用的系统最小版本以及目标(最佳)版本,应用版本号等信息。
defaultConfig {
applicationId 'com.sky.v1'
minSdkVersion 15
targetSdkVersion 23
multiDexEnabled true // 开启multidex
versionCode 985
versionName 9.8.5
buildConfigField "boolean", "IS_FREE", "true" //自定义配置字段
}
需要注意的是,applicationId会覆盖manifest里设置的packagename成为应用的唯一标识。另外,使用buildConfigField也可以自定义配置字段,gradle build完成后会生成BuildConfig class,自定义字段会被添加到其中。根据自定义配置字段值,我们在代码中就可以作不同逻辑处理。BuildConfig默认提供了一些配置字段,如下所示:
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.sky.v1";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = -1;
public static final String VERSION_NAME = "";
public static final boolean IS_FREE = true;
}
- buildTypes
buildTypes声明gradle build的类型。默认情况下,包含release和debug两种配置,即可以build出应用的release版本和debug版本。针对release和debug版本,我们可以进行不同的配置,从而达到想要的效果。例如,proguard混淆,通常release版本才需要代码混淆,debug版本为了方便调试关闭混淆。当然,我们也可以自定义build类型。
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
- productFlavors
和buildTypes有点类似,productFlavors也可以实现build出不同类型的apk。当项目需要打包不同版本(渠道)的apk,但是每个apk之间差别很小的时候,可以通过productFlavors来配置,gradle会对每一个配置的flavor分别打包,这样就不需要我们手动修改代码或者资源重新build。例如,针对不同应用市场发布android版本,可能使用不同的资源、sdk等,这时就可以使用productFlavors来解决问题。每个flavor可配置字段和defaultConfig一致。
productFlavors {
common {
}
qihoo {
}
yingyongbao {
}
meizu {
}
}
Build Variant
gradle在build时是根据buildTypes和productFlavors的配置共同决定的,我们可以这么理解:build variant = (flavor, build type)。也就是说,按照上面的例子,总共有2*4,即8种build variant,commonRelease,commonDebug,qihooRelease等。理解build variant很重要,我们可以看到gradle tasks中有很多task名字都包含build variant。
Tasks
gradle所有的工作都是由一个个task组成的,根据上面的截图可以看出主要包括assemble、check、build、clean等task。
- assemble 编译并打包代码和资源输出apk或者aar
- check 检查测试代码,比如lint检查,UT等。
- build 组合了check和assemble操作
- clean 清理之前的输出以及生成的文件,比如build目录
gradle为不同的product flavor,build type以及build variant都创建了对应的一些task,例如assembleCommon、assembleRelease、assembleCommonRelease等。各个task之间存在依赖关系,例如assembleCommon依赖assembleCommonRelease和assembleCommonDebug等。
参考文档:
http://tools.android.com/tech-docs/new-build-system/user-guide