为什么选择Gradle 如你是一个开发者,项目自动构建是你每天工作的一部分,难道你就不想让你的构建代码和你写的源代码一样可以扩展、测试和维护?Gradle的构建脚本是声明式的、可读的,可以清晰的表达意图。使用Groovy代替XML来写代码大大减少了构建代码的大小。更重要的是,Gradle集成了其他构建工具,比如Ant和Maven,使得原来的项目很容易迁徙到Gradle。
案例
不同的配置
相信每位不容易的android开发者都会有这样的需求,某个项目一般会有一个测试服地址和一个正式服地址,项目版本迭代都是先在测试服上面测试通过后,服务器在部署正式服地址的服务器,然后在构建一个正式服地址给测试人员。测试服情况下app需要有一些日志开关或者一些只能在测试服出现的UI或者配置,没用gradle构建变种版本之前,我们一般都是手动去改那些配置
多渠道apk
有这样的需求就是,应用能有收费版本或者免费版本或者会有不同的发包渠道,这种情况就是每个渠道版本的配置信息都是不一样的,如果渠道只有几个还好我们可以直接利用工具进行手动signature pak,一旦渠道有几十个的情况下。手动signature方式就不合适了,我们需要每个每个的去signature,这样就没法工作了。
配置多个变种版本 完整的变种版本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 apply plugin: 'com.android.application' def releaseTime() { return new Date().format("MMddHHmm", TimeZone.getTimeZone("GMT+08:00")) } android { flavorDimensions "default" compileSdkVersion 26 buildToolsVersion '26.0.2' defaultConfig { applicationId "com.jinwei.me" minSdkVersion 18 targetSdkVersion 24 versionCode 1101 versionName "1.1.01" multiDexEnabled = true } signingConfigs { release { storeFile file("./test") storePassword "aaaaaa" keyAlias "rc" keyPassword "aaaaaa" } } buildTypes { release { minifyEnabled true proguardFiles 'proguard-rules.pro' signingConfig signingConfigs.release applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { def fileName = "Test${variant.productFlavors[0].name}.apk" outputFileName = fileName } } } } } productFlavors { 正式服发版包 { /*是否正式服地址*/ buildConfigField "boolean", "RELEASE", "true" /*是否使用ANDROID_ID*/ buildConfigField "boolean", "ANDROID_ID", "true" /*是否使用打开邮箱注册*/ buildConfigField "boolean", "OPEN_EMAIL", "false" /*是否打开日志*/ buildConfigField "boolean", "OPEN_LOG", "false" } 正式服 { /*是否正式服地址*/ buildConfigField "boolean", "RELEASE", "true" /*是否使用ANDROID_ID*/ buildConfigField "boolean", "ANDROID_ID", "false" /*是否使用打开邮箱注册*/ buildConfigField "boolean", "OPEN_EMAIL", "true" /*是否打开日志*/ buildConfigField "boolean", "OPEN_LOG", "true" } 测试服 { /*是否正式服地址*/ buildConfigField "boolean", "RELEASE", "false" /*是否使用ANDROID_ID*/ buildConfigField "boolean", "ANDROID_ID", "false" /*是否使用打开邮箱注册*/ buildConfigField "boolean", "OPEN_EMAIL", "true" /*是否打开日志*/ buildConfigField "boolean", "OPEN_LOG", "true" } } } repositories { mavenCentral() google() flatDir { dirs 'libs' } } dependencies { testCompile 'junit:junit:4.12' }
首先进入到app级别下的gradle中,gradle构建需要配置签名信息我们先配置一个。
1 2 3 4 5 6 7 8 9 10 11 12 13 signingConfigs { release { storeFile file("./test") storePassword "aaaaaa" keyAlias "rc" keyPassword "aaaaaa" } debug { storeFile file("./test") storePassword "aaaaaa" keyAlias "rc" keyPassword "aaaaaa" }
这个信息可以ide生成一个key填写签名信息然后存储到app目录下面。
配置完后,接着在配置不同的版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 productFlavors { 正式服发版包 { /*是否正式服地址*/ buildConfigField "boolean", "RELEASE", "true" /*是否使用ANDROID_ID*/ buildConfigField "boolean", "ANDROID_ID", "true" /*是否使用打开邮箱注册*/ buildConfigField "boolean", "OPEN_EMAIL", "false" /*是否打开日志*/ buildConfigField "boolean", "OPEN_LOG", "false" } 正式服 { /*是否正式服地址*/ buildConfigField "boolean", "RELEASE", "true" /*是否使用ANDROID_ID*/ buildConfigField "boolean", "ANDROID_ID", "false" /*是否使用打开邮箱注册*/ buildConfigField "boolean", "OPEN_EMAIL", "true" /*是否打开日志*/ buildConfigField "boolean", "OPEN_LOG", "true" } 测试服 { /*是否正式服地址*/ buildConfigField "boolean", "RELEASE", "false" /*是否使用ANDROID_ID*/ buildConfigField "boolean", "ANDROID_ID", "false" /*是否使用打开邮箱注册*/ buildConfigField "boolean", "OPEN_EMAIL", "true" /*是否打开日志*/ buildConfigField "boolean", "OPEN_LOG", "true" } }
buildConfigField就是我们需要用到的字段,可以看到每个产品的类型都是不一样的。
配置buildTypes,这里我们指定了signingConfig为release的签名 信息,就是我们刚刚配置的。如果有需求也可以指定debug的签名信息。这里的release{} debug{} build的时候会选择对应的build信息,applicationVariants.all 我们还自动对apk名字进行了命名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 buildTypes { release { minifyEnabled true proguardFiles 'proguard-rules.pro' signingConfig signingConfigs.release applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { def fileName = "Test${variant.productFlavors[0].name}_${releaseTime()}.apk" outputFileName = fileName } } } } debug { minifyEnabled true proguardFiles 'proguard-rules.pro' signingConfig signingConfigs.release applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { def fileName = "Livu${variant.productFlavors[0].name}_${releaseTime()}.apk" outputFileName = fileName } } } } }
配置完成后进行编译,我们搜索一下类BuildConfig,可以看到build的时候已经自动读取了对应的配置信息了。然后我们可以根据这些字段信息来做对应的逻辑操作了,比如如果日志开关为true的情况下我们才打印log日志,如果RELEASE为true我们就使用正式服地址如果是false的话我们就使用测试服地址。
1 2 3 4 5 // Fields from product flavor: 测试服 public static final boolean ANDROID_ID = false; public static final boolean OPEN_EMAIL = true; public static final boolean OPEN_LOG = true; public static final boolean RELEASE = false;
我们可以选择这里切换版本信息,对应的也会自动读取配置的信息。
手动打包的方式可以看也多了,三个不同类型的Flavors。
使用gradlew可以直接自动构建 mac下./gradlew开头 windows下面用gradlew开头
构建全部Flavors的debug和Release包
1 2 3 gradlew assemble测试服Release build测试服的Release包 gradlew assemble测试服Deubg build测试服的Debug包 gradlew assembleRelease build全部Flavors的Release包
到这里就完成了变种版本的配置,基本来说比较简单。
后续的学习
Gradle In Action(Gradle实战)中文版
Gradle Android插件用户指南翻译