由于android应用分发渠道无数,很多时候需要对应不同的渠道做相应的资源文件上甚至功能上的定制,比如上360首发需要在launcher页上面加上360logo,有些应用市场是禁止应用的自动更新功能还有之前上百度市场需要集成sdk,幸好gradle提供应对这个情况的解决方案,轻松应对这个dirty work。
一 Build Variants
假设我们需要打三个不同的版本的apk,一个供自己官网下载,一个百度市场,一个小米市场。我们在工程build.gradle文件增加如下配置
android {
....
productFlavors {
baidu {
}
xiaomi {
}
other {
}
}
}
然后Build->Generate Signed Apk
最后生成了3个apk
*在Android Studio调试时切换不同的Variants
在Android Studio的最右边靠下有个Build Variants点开,然后就可以选择想调试的Variant
二 对于不同渠道不同资源的处理
假设小米应用市场和百度应用市场都需要在某个页面打上各自独家logo,就是需要将drawable/lily_lake.png 在不同渠道打上不同渠道的logo
1. 在src文件创建和上面配置相同的名字的文件夹,具体如下
2. 在与原资源类似的目录下添加打上logo的图片,如下图,gradle在打包的时候就会根据不同的Variant提取相应的资源。
3. 不仅图片,字符资源也是可以定制的
假设我们在百度应用市场首发,我们的应用名改成 “百度首发XXX”。同样的我们在baidu的资源文件夹下添加一个string资源文件,然后添加:
<resources>
<string name="app_name">百度首发XXX</string>
</resources>
三 AndroidManifest.xml 以及 BuildCofig.java
1. 在AndroidManifest.xml添加
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
UMENG_CHANNEL_VALUE 可以在打包的时候根据不同的variant然后赋值
productFlavors{
baidu{
manifestPlaceholders = [UMENG_CHANNEL_VALUE:"baidu"]
}
other{
manifestPlaceholders = [UMENG_CHANNEL_VALUE:"other"]
}
xiaomi{
manifestPlaceholders = [UMENG_CHANNEL_VALUE:"xiaomi"]
}
}
或这么写
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [ UMENG_CHANNEL_VALUE:name ]
}
应用场景:不同渠道需要建立不同的数据统计(使用友盟之类也会用到),那么我们可以读取AndroidManifest该应用的分发渠道。
ApplicationInfo appInfo = null;
try {
appInfo = getPackageManager()
.getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA);
String msg=appInfo.metaData.getString("UMENG_CHANNEL");
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
2. BuildCofig.java 可以通过gradle增加其字段
android{
defaultConfig {
...
//添加配置文件字段
buildConfigField "boolean", "AUTO_UPDATES", "true"
}
}
productFlavors{
baidu{
//赋值
buildConfigField "boolean", "AUTO_UPDATES", "false"
}
}
应用场景:有的应用市场不允许应用自动更新,那么我们BuildCofig.java增加一个字段判断是否需要增加自动更新功能
if(BuildConfig.AUTO_UPDATES){
// 更新
}else {
// 不自动更新
}