批量修改生成的apk文件名
在我们打包发版的时候,一次性打几十个包,这时候我们就想让生成的apk文件名有区分,比如一眼就能看出这个apk是哪个版本的,哪个渠道的,是哪天打的包等等,这就需要我们在生成apk文件的时候动态修改生成的apk文件名达到这一目的。这里以我们的产品随手记为例:
def buildTime() {
def date = new Date()
def formattedDate = date.format('yyyyMMdd')
return formattedDate
}
android {
buildTypes {
release {
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (output.outputFile != null && output.outputFile.name.endsWith('.apk')
&&'release'.equals(variant.buildType.name)) {
def apkFile = new File(
output.outputFile.getParent(),
"Mymoney_${variant.flavorName}_v${variant.versionName}_${buildTime()}.apk")
output.outputFile = apkFile
}
}
}
}
}
}
以baidu渠道为例,以上的代码会生成一个名字为Mymoney_baidu_v9.5.2.6_20150330.apk安装包。下面我们分析一下,Android Gradle任务比较复杂,它的很多任务都是自动生成的,为了可以更灵活的控制,Android Gradle提供了applicationVariants、libraryVariants以及testVariants,他们分别适用于app、library、app和library都适用。
这里是循环处理每个applicationVariant,当他们的输出文件名以apk结尾并且buildType是release时,重新设置新的输出文件名,这样就达到了我们批量修改生成的文件名的目的。
AndroidManifest里的占位符
AndroidManifest.xml这是一个很重要的文件,我们的很多配置都在这里定义。有时候我们的一些配置信息,比如一个第三方应用的key,第三方统计分析的渠道号等也要在这里进行配置。这里以友盟统计分析平台为例,演示这一功能的使用。在友盟统计分析中,我们需要根据渠道进行统计,比如google,百度,应用宝等渠道的活跃新增等,友盟的SDK是在AndroidManifest里配置一个name为UMENG_CHANNEL的meta-data,这样这个meta-data的值就表示这个apk是哪个渠道,我们版本发布有几十个渠道,以前ant打包的时候是采用文字替换的办法,现在Gradle有更好的处理办法,那就是manifestPlaceholders,它允许我们动态替换我们在AndroidManifest文件里定义的占位符。
<meta-data android:value="${UMENG_CHANNEL_VALUE}" android:name="UMENG_CHANNEL"/>
如上${UMENG_CHANNEL_VALUE}就是一个占位符,然后我们在gradle的defaultConfig;里这样定义脚本:
android {
defaultConfig {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: 'dev']
}
}
以前的意思就是我们的默认配置里AndroidManifest的${UMENG_CHANNEL_VALUE}占位符会被dev这个字符串所替换,也就说默认运行的版本是一个开发板。以此类推,我们其他渠道的版本就可以这样定义:
android {
productFlavors {
google{
applicationId "org.flysnow.demo.google"
manifestPlaceholders.put("UMENG_CHANNEL_VALUE",'google')
}
baidu{
applicationId "org.flysnow.demo.baidu"
manifestPlaceholders.put("UMENG_CHANNEL_VALUE",'baidu')
}
}
}
这样有多少个渠道就做多少次这样的定义,即可完成分渠道统计。但是如果上百个渠道,这样一个个写的确太累,很麻烦,我们继续研究,同学们有没有发现,我们的渠道名字和我们的flavorName一样,我们用这个flavorName作为UMENG_CHANNEL_VALUE不就好了吗,可以批量的替换吗?当然可以,这又体现了我们Gradle的强大和灵活之处。
productFlavors.all { flavor ->
manifestPlaceholders.put("UMENG_CHANNEL_VALUE",name)
}
循环每个flavor,并把他们的UMENG_CHANNEL_VALUE设置为他们自己的name名字,ok,搞定。
最后可以看这个,eclipse gradle 双向支持。
http://rinvay.github.io/android/2015/04/09/Build-Android-with-Gradle/
gradle 实例
http://jeepxiaozi.github.io/androidkai-fa-zhi-gradlebi-ji-zheng-li-2-gradlechang-yong-ming-ling-ji-umengduo-qu-dao-da-bao-shi-zhan.html
github 不错的文章
https://github.com/rujews/android-tech-docs/blob/master/new-build-system/user-guide/README.md