构建与打包能力系列
1、什么是多渠道
渠道包就是要在安装包apk中添加渠道信息,也就是channel,对应不同的渠道,例如:小米市场、360市场、应用宝市场等,需要为每个apk包设定一个可以区分渠道的标识,这个为apk包设定应用市场标识的过程就是多渠道打包。
2、gradle实现多渠道打包的方式
其核心原理就是在编译时通过gradle修改AndroidManifest.xml中的meta-data占位符的内容,执行N次打包流程,然后就可以在java中通过API获取对应的数据。
BuildTypes、Flavors、BuildVariants三个定义:
(1)BuildTypes:构建类型,gradle组件默认提供给了debug、release类型。
(2)Flavors:产品渠道,可以根据productFlavors,针对不同的渠道生产个性化apk。
(3)BuildVariants:每一个buildType和flavor组成一个buildVariant。
- Mainfest配置渠道占位符
<meta-data
android:name="channel"
android:value="${channel_value}" />
- app模块的build.gradle
android {
//产品维度,没有实际意义,但gradle要求
flavorDimensions 'default'
//productFlavors是android节点的一个节点
productFlavors {
baidu {}
xiaomi {}
}
//如果需要在不同渠道统一配置,使用productFlavors.all字段替换manifest里面channel_value的值
productFlavors.all { flavor ->
manifestPlaceholders = [channel_value: name]
}
//设置渠道包名称->howow-xiaomi-release-1.0.apk
applicationVariants.all { variant ->
variant.outputs.all { output ->
//output即为该渠道最终的打包产物对象,设置它的outputFileName属性
outputFileName = "howow-${variant.productFlavors[0].name}_${variant.buildType.name}_${variant.versionName}.apk"
}
}
}
- 运行时获取渠道信息
private String getChannel() {
PackageManager pm = getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
return appInfo.metaData.getString("channel_value");
}
但是,这种方式存在一些缺点:
(1)每生成一个渠道包,都要重新执行一遍构建流程,效率太低,只适用于渠道较少的场景。
(2)Gradle会为每个渠道包生成一个不同的BuildConfig.java类,记录渠道信息,导致每个渠道包的dex的CRC值都不同。
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.example.myapplication";
public static final String BUILD_TYPE = "debug";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
//增加了productflavor之后,这里的值,每个apk都不同
public static final String FLAVOR = "";
}
如果使用了微信的Tinker热补丁方案,那么就需要为不同的渠道包打不同的补丁,因为Tinker是通过对比基础包base.apk和新包new.apk生成差分补丁patch.apk,然后再把补丁patch.apk和已安装的基础包old base.apk一起合成新的apk。
这就要求用于生成差分补丁的基础包base.apk里面的DEX和已安装的基础包old base.apk里面的DEX是完全一致的,就是说手机上安装的是应用宝渠道包,那必须使用应用宝渠道包来生成补丁patch.apk,才能合并成功。