一、前言
在 App 开发完成上架的时候,我们可能需要对上架到各个应用商店的 apk 包做一些区分,方便后续一些相关业务的开展。因此我们就需要在 App 打包的时候,给上架到不同应用商店的 Apk 中写入不同的渠道信息。这个时候,我们就需要进行多渠道打包了。多渠道打包也是有许多知识需要进行学习,在这里我们就只针对官方提供的多渠道打包方法做一下简单的介绍。
二、认识 flavorDimension 和 productFlavor
flavorDimension 翻译过来叫做风味维度,productFlavor 则叫做产品风味。它们两者之间的关系紧密相连:每一个产品风味都必须归属于某一个特定的风味维度,而每一个风味维度则至少要有一个产品风味。这里面,风味维度相当于充当了 组 的角色,而产品风味则是充当了 成员 的角色,每一个成员属于特定的小组,每一个小组则至少要有一个成员。最终打包的时候,就是从不同的小组中抽取成员进行组合,再将各个成员里面包含的信息写到 Apk 里面,得到不同的 Apk 包。这样说可能有点抽象,不太好理解,下面我们会结合具体的代码和最终结果来补充说明。
三、实例演示
我们先创建一个新的工程项目,然后打开 app 模块下的 build.gradle。
- 如果我们只是单纯的想要对不同的应用商店包做区分,那么我们只需要在 flavorDimensions 中添加一个风味维度(比如 channel),然后在 productFlavors 中添加不同的产品风味,代码如下:
android {
//省略其他无关代码...
flavorDimensions "channel"
productFlavors {
huawei {
// dimension 用于标识该产品风味属于 channel 这个风味维度
dimension "channel"
}
xiaomi {
dimension "channel"
}
}
}
这样,我们就可以打出不同渠道的包了。我们先点击一下同步按钮进行同步,同步完成之后,我们就可以在 Android studio 左侧的 Build Variants中看到,Active Build Variant这一选项,已经由原来的 debug 和 release 2项变为如下 4 项:
分别是 huaweiDebug 和 huaweiRelease,以及 xiaomiDebug 和 xiaomiRelease。
可能这里就有小伙伴要问了:“不同的渠道包是有了,但是要怎样判断当前是什么渠道包,这样我才能完成有关渠道的业务需求啊?”
这个问题问得好。
我们在完成上面的操作之后呢,是可以打出不同的渠道包了,不过还缺少了一个最重要的环节,就是给不同的产品风味写入不同的配置信息,这样我们才能根据不同的配置信息来判断是哪个渠道的包。我们修改一下 build.gradle中的代码,修改后代码如下:
android {
//省略其他无关代码...
flavorDimensions "channel"
productFlavors {
huawei {
manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
// dimension 用于标识该产品风味属于 channel 这个风味维度
dimension "channel"
}
xiaomi {
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
dimension "channel"
}
}
}
可以看到,我们给每一个产品风味都添加了一个 manifestPlaceholders ,里面有一个 key - value,key 都是 CHANNEL_VALUE,值则分别是 huawei 以及 xiaomi。这样,我们在打不同渠道包的时候,CHANNEL_VALUE 这个 key 所对应的 value 就会被赋予不同的值,下面我们通过代码来验证一下。
我们在 AndroidManifest 中把这个 CHANNEL_VALUE 用起来:
<application
//省略其他无关代码...
<meta-data
android:name="CHANNEL"
android:value="${CHANNEL_VALUE}" />
</application>
然后我们修改一下 MainActivity 中的代码,修改后代码如下:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 获取 channel 信息
Log.d(TAG, "CHANNEL: ${getAppChannel()}")
}
private fun getAppChannel(): String? {
val metadata =
packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData
return metadata.getString("CHANNEL")
}
companion object {
private const val TAG = "MainActivity_Flavor"
}
}
我们在 Android studio 左侧的 Build Variants 切换 Active Build Variant到 huaweiDebug,然后点击一下运行按钮,可以看到如下图所示:
我们再切换到 xiaomiDebug,再次运行程序,可以看到:
可以看到,当我们运行不同渠道的应用程序时,CHANNEL_VALUE 的值是不一样的。这样,我们就在代码中区分当前渠道是什么渠道了。
- 如果我们不单单想要区分不同商店的包,还要区分相同商店不同类型的包,比如在华为上架了两个包,一个是免费版,一个是付费版。那么我们就需要在 flavorDimensions 中再添加一个风味维度(比如 mode),然后在 productFlavors 中再添加对应的产品风味就行,代码如下:
flavorDimensions "channel", "mode"
productFlavors {
huawei {
manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
// dimension 用于标识该产品风味属于 channel 这个风味维度
dimension "channel"
}
xiaomi {
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
dimension "channel"
}
free {
// 除了用 manifestPlaceholders, 也可以通过 buildConfigField 来配置信息
buildConfigField "boolean", "IS_VIP", "false"
dimension "mode"
}
pro {
buildConfigField "boolean", "IS_VIP", "true"
dimension "mode"
}
}
再同步一下项目,我们可以在左侧的 Build Variants 中看到,Active Build Variant这一选项又有了变化,结果如下:
同样,我们修改一下 MainActivity 的代码来验证一下:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 获取 channel 信息
Log.d(TAG, "CHANNEL: ${getAppChannel()}")
// 获取 mode 信息
Log.d(TAG, "IS_VIP: ${isVipMode()}")
}
private fun getAppChannel(): String? {
val metadata =
packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData
return metadata.getString("CHANNEL")
}
private fun isVipMode(): Boolean {
return BuildConfig.IS_VIP
}
companion object {
private const val TAG = "MainActivity_Flavor"
}
}
在 Android studio 左侧的 Build Variants 选择 xiaomiProDebug ,编译运行之后可以看到如图所示
我们再切换到 huaweiFreeDebug,再次运行程序,可以看到:
所以,通过这种方式,我们就可以在代码中判断是什么渠道什么类型的 Apk 包了。
四、关于渠道包的数量
上述例子中,每一个渠道包由 [channel][mode][buildType] 组成, 总数量为 [channel 风味组成员数量] _ [mode 风味组成员数量] _ [buildType(构建类型,没特殊设置的话,则是 debug 或 release 其中一种)类型数量] ,如例子中则为 2 * 2 * 2 = 8。
五、最后
关于多渠道打包,还有比较多的内容需要学习了解,这里只是简单介绍一下最基本的官方多渠道打包方式,如有错误的地方,欢迎指出,谢谢。