什么是Gradle
你可以看一下Gradle主页。
简单来说,Gradle是一个自动化编译部署测试工具。Gradle内容很广,还有专门的书介绍Gradle。而Android Studio使用的是Gradle中的一部分功能。
build.gradle
build.gradle就是Android Studio使用的Gradle文件,下面是一个最简单的build.gradle示例:
- buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:0.6.+'
- }
- }
- apply plugin: 'android'
- android {
- compileSdkVersion 17
- }
buildscript {...} 配置编译代码,这部分基本上不用怎么编辑;
apply plugin: 'android' 是表示用android插件;
android {...} 就是android插件的配置了。具体配置内容以及取值可以看这里
Build Task
Gradle中用Task来代表一系列操作,有点类似于Makefile中的Target。常见的Tasks有:
- assemble
- build
- check
- clean
根据名字基本就能知道Task作用,其中build = assemble + check。
执行task直接就是在命令行执行gradle [task],例如: gradle assemble
gradle assembleRelease
Build参数配置
Gradle脚本中的参数是DSL规范的,即使用的是类似于Java包名的方式:
- a.b.c = 1
- a {
- b {
- c 1
- }
- }
上面两种方式表示的是一个意思。 可以配置的参数这里不做详述,请到http://tools.android.com/tech-docs/new-build-system/user-guide查阅。
下面讲几个主要使用的参数。
Build Types
TODO
Signing Configurations
在生成APK的时候,有一步是用一个Key给APK签名,关于签名的配置项都在signingConfigs中:
- signingConfigs {
- myConfig {
- storeFile file("path-to-keystore")
- storePassword "******"
- keyAlias "******"
- keyPassword "******"
- }
- }
然后在编译类型中引用:
- buildTypes {
- release {
- ...
- signingConfig signingConfigs.myConfig
- }
- }
这样签名的配置就好了。不过按上文配置,有一个问题:build.gradle经常是会提交到代码管理系统中,而显然把key明文放在代码库里不怎么安全(特别如果你写的是开源项目)。一个替代的方案是输入密码,或者将密码存储在环境变量中,可以参看这个链接:http://stackoverflow.com/questio ... k-file-using-gradle
- ...
- signingConfigs {
- release {
- storeFile file(System.getenv("KEYSTORE"))
- storePassword System.getenv("KEYSTORE_PASSWORD")
- keyAlias System.getenv("KEY_ALIAS")
- keyPassword System.getenv("KEY_PASSWORD")
- }
- }
Product flavors
如果你一个项目想要生成不同的APK包,有不同的包名,或者不同的资源,那么这就是使用Product flavors的时候了。
- android {
- ....
- productFlavors {
- flavor1 {
- packageName "com.example.flavor1"
- versionCode 20
- }
- flavor2 {
- packageName "com.example.flavor2"
- minSdkVersion 14
- }
- }
- }
上面的示例会生成两个不同的APK包,有着不同的包名以及属性。Product flavors里边可以设置的属性,参照http://tools.android.com/tech-docs/new-build-system/user-guide。
友盟多渠道打包
看了上面这么多,现在来一个示例:写一个build.gradle完成友盟多渠道打包。 友盟渠道区分是通过在AndroidManifest.xml的<meta-data>实现的:
- <meta-data android:value="UMENG_CHANNEL_VALUE" android:name="UMENG_CHANNEL"/>
所以基本的思路就是,在打包的时候替换AndroidManifest.xml中的字符串以打出不同的APK包。 build.gradle关键部分如下:
- android {
- compileSdkVersion 19
- buildToolsVersion '19.0.0'
- defaultConfig {
- minSdkVersion 7
- targetSdkVersion 19
- }
- // 签名信息,都存在环境变量中
- signingConfigs {
- release {
- storeFile file(System.getenv("KEYSTORE"))
- storePassword System.getenv("KEYSTORE_PASSWORD")
- keyAlias System.getenv("KEY_ALIAS")
- keyPassword System.getenv("KEYSTORE_PASSWORD")
- }
- }
- buildTypes {
- release {
- runProguard true
- proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
- signingConfig signingConfigs.release //使用上述签名信息
- }
- }
- productFlavors {
- defaultFlavor {
- proguardFile 'proguard-rules.txt'
- }
- // 需要打不同的版本
- xiaomi {
- }
- LeTv {
- }
- }
- }
- // 下面这段代码摘自 <a href="https://github.com/umeng/umeng-muti-channel-build-tool/tree/master/Gradle" target="_blank" style="color: rgb(0, 136, 204); text-decoration: none;">https://github.com/umeng/umeng-muti-channel-build-tool/tree/master/Gradle</a>
- // 实现用productFlavor名字替换AndroidManifest.xml 中的 UMENG_CHANNEL_VALUE 字符串
- android.applicationVariants.all { variant ->
- variant.processManifest.doLast{
- copy{
- from("${buildDir}/manifests"){
- include "${variant.dirName}/AndroidManifest.xml"
- }
- into("${buildDir}/manifests/$variant.name")
- filter{
- String line -> line.replaceAll("UMENG_CHANNEL_VALUE", "${variant.productFlavors[0].name}")
- }
- variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml")
- }
- }
- }
在修改完build.gradle之后,需要使用Android Studio的sync Project with gradle files功能同步工程设置。 之后就在Android Studio的Terminal中输入gradle build(windows是gradlew build),稍等片刻,所有生成的APK都在你工程的build/apk下啦!