加入新公司后,将项目从Eclipse转到了Android Studio,转换后第一个需要解决的就是编写新的打包脚本。
Studio默认使用gradle打包,对于gradle还不熟悉的同学,可以先去看看这两篇文章
我们当时主要面临三个问题:
1、不同环境:开发,测试,正式三套环境,api地址,第三方推送配置等都不相同;
2、Android有着众多的市场,在打正式包时,我们需要区分不同的渠道,便于统计下载量及分析不同渠道的相关数据情况,需要发布多个渠道包;
3、打出的文件名等需要定制化并区分渠道和环境等;
上述问题在gradle中都可以在build.gradle脚本文件中的配置。
首先解决第一个问题,在buildTypes中分别定义三套不同环境的配置:
buildTypes {
debug {
manifestPlaceholders = [AppID : "XXX", AppSecret : "XXX", AppKey : "XXX",UMEN_AppKey : "XXX"]
buildConfigField "String", "SERVER_PATH", "\"http://debug.com\""
buildConfigField "boolean", "LOG_DEBUG", "false"
buildConfigField "String", "CHANNEL", "\"000\""//渠道号
versionNameSuffix "-de"
}
qatest {
manifestPlaceholders = [AppID : "XXX", AppSecret : "XXX", AppKey : "XXX",UMEN_AppKey : "XXX"]
buildConfigField "String", "SERVER_PATH", "\"http://qatest.com\""
buildConfigField "boolean", "LOG_DEBUG", "false"
buildConfigField "String", "CHANNEL", "\"000\""//渠道号
versionNameSuffix “-qa"
}
release{
manifestPlaceholders = [AppID : "XXX", AppSecret : "XXX", AppKey : "XXX",UMEN_AppKey : "XXX”]Ï
buildConfigField "String", "SERVER_PATH", “\”http://release.com\""
buildConfigField "boolean", "LOG_DEBUG", "false"
buildConfigField "String", "CHANNEL", "\"000\""//渠道号
versionNameSuffix “-qa"
}
}
其中:
manifestPlaceholders用来替换在AndroidManifest文件中定义好的变量值,上例中前三个变量是个推的配置,最后一个是友盟统计;在文件中使用${UMEN_AppKey},则打包时会自动替换对应的值”XXX"。
buildConfigField用来创建一个全局静态常量,在程序中可以用BuildConfig.CHANNEL来使用该常量;
versionNameSuffix 表示是否给版本名称添加后缀,方便在测试时区分对应的是哪个环境版本的包。
在命令行运行:
./gradlew assembleDebug
./gradlew assembleQatest
./gradlew assembleRelease
即会生成不同的变量值。
上一步已经解决了如何区分不同环境包对应的一些配置信息,接下来解决多渠道打包问题。我们的应用中自定义了一套统计方式,而区分各个渠道只需要在程序中为不同渠道生成一个唯一的渠道号即可;可以如下添加:
productFlavors {
company {
buildConfigField "String", "CHANNEL", "\"000\"" // 官方包
}
tencent {
buildConfigField "String", "CHANNEL", "\"001\"" // 应用宝
}
baidu {
buildConfigField "String", "CHANNEL", "\"002\"" // 百度手机助手
}
...
}
这样在执行上述命令./gradlew assembleDebug时,就会生成三个或更多地渠道包(开发环境),而每个包都将有一个唯一的渠道号(CHANNEL)。
注意运行上述命令将会打出所有的渠道,如果想单独打一个渠道包,则运行下述命令即可:
./gradlew assembleCompanyDebug
最后,我们虽然生成了多个渠道包,但是包名的规则还未确定。比如你想要生成的包名如下格式:
应用名_渠道名_版本号.apk
wahaha_baidu_v1.0.apk
可以使用如下方式:
在buildTypes中添加如下代码:
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
// 输出apk名称为wahaha_001_wandoujia_v1.0.apk
if (variant.buildType.name.equals("debug")) {
def fileName = "wahaha_debug_v${defaultConfig.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}else if(variant.buildType.name.equals("qatest")){
def fileName = "wahaha_qatest_v${defaultConfig.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}else if(variant.buildType.name.equals("release")){
def fileName = "wahaha${variant.productFlavors[0].name}_v${defaultConfig.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
gradle对于多渠道和不同环境打包的支持非常优雅,也是Google官方推荐的打包方式,除了上面这些功能,还有很多支持的功能如:代码混淆,zip对齐,dex超过65535限制等等,在前面两篇文章中都有讲解,大家有什么问题也可以在评论中一起探讨。