在大部分统计分析服务中为了追踪App的渠道来源都需要在App中设下标示来标记App的分发来源。友盟的统计分析SDK的做法是在 AndroidManifest.xml
文件中配置一项Meta-data
来标记渠道的,如
<meta-data
android:name="UMENG_CHANNEL"
android:value="Umeng" >
</meta-data>
对于开发者而言,不同的渠道只要修改这个渠道标识就可以了,但是对于国内的Android市场,各种市场、广告和其他分发平台不下百家,如果每次 重新修改渠道标识再打包是一个巨大且无味的工程,所以各种自动化打包的方案就出来了。
大家在开发App的时候如果是在Eclipse环境下,基本上是通过 Android Tools -> Exports (Un)Signed Application Package ...
来打包的,
但是实际上还可以通过配置ant脚本来打包。执行 android update project –p XXXX –t XXXX
就会发现工程的根目录下多了几个文件,其中
最重要的就是build.xml
这个文件中配置了输出apk的ant脚本。
(如果不知道ant是什么看下这里) 现在有了可以 通过简单的ant命令就可以打包的方法了,那么下面只要写几行代码在每次打包之前替换渠道就可以了。
替换渠道是很简单的事,因为AndroidManifest.xml文件只是一个简单的文本文件,你可以写正则或者用xml解析的方式更新友盟渠道的值。 使用这种方式打包的缺点是需要使用 ant (不熟悉的同学可能觉得不方面),因为 ant 的许多配置本身也很麻烦。
Gradle的Android插件是Google发布 AndroidStudio的时候提供的,同Ant比起来,Gradle好用多了,可以看一下之前的介绍 因为Gradle的项目描述是使用 Groovy 语言做的,所以能够直接在打包脚本中写一些代码来完成渠道的替换.
利用 Android Gradle 的 ProductFlavor 功能添加多个渠道,每个渠道都是一个Flavors
//渠道
productFlavors {
wandoujia{
//这里可以写一些更详细的配置,如果不需要的话,可以忽略
}
appchina{
}
}
在处理 AndroidManifest.xml 文件时添加一个钩子(hook)替换渠道,注意,这里面这是做了一个简单的字符串替换,需要在原来的
AndroidManifest.xml 文件中添加:
android.applicationVariants.all{ variant ->
println "${variant.productFlavors[0].name}"
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")
}
}
}
PS:目前看来这是最靠谱的打包方式,同Ant方式比配置简单,自定义能力强,同后面提到的反编译的方式比较,虽然速度上不及(每次重新打包资源) 但是稳定性可以保证,通过反编译的方式会对原有的apk进行修改,这些修改可能造成意外的问题。所以建议大家以后都通过这种方式打包。
这种打包方式不需要源码,只要一个apk就可以了,操作起来比较简单,但是由于修改了原来apk的缘故,可能会出现一些莫名其妙的错误。 一种比较常见的做法是使用 apktool 这个工具,他有两个主要命令
使用apktool打包的方式是反编译之后可以得到纯文本格式的AndroidManifest.xml文件,编辑这个文件修改其中的渠道然后再重新打包成apk。
但是apktool工具是一个破解工具稳定性无法保证,而且至今为止已经发现了很多问题,比如打包在 jar中的资源重新打包的时候会丢失等等, 但是对于apk而言只是要修改AndroidManifest.xml文件就够了。所以后来研究了一遍AndroidManifest.xml(AXML)文件二进制格式的结构之后我写了一 个专门用来解析AXML文件的工具. 并提供非常简单的编辑功能,可以用来替换AXML中的渠道标识。
通过Eclipse插件打包,Eclipse 的插件功能非常好,包括ADT也只是Eclipse的一个插件而已,于是有人专门写了这样的一个插件,可以看看 这里.
还有一种开发者经常提到的方式,用 aapt 命令往 apk 的assert目录插入一个文件作为渠道标示,然后在代码中读取这个渠道通过代码设置渠道。
nTop 28 November 2014