注册

Android 通过productFlavors实现多渠道打包

在日常开发中,可能会遇到同一份代码,需要根据运营需求打出不同包名、不同图标、不同名称的Apk,发布到不同的渠道中。Android Studio提供了便捷的多渠道打包实现方法productFlavors


本文介绍一下使用productFlavors来实现多渠道打包。


创建productFlavors



  • 添加Dimension

在app包下的build.gradle中的android闭包下,添加flavorDimension,代码如下:


android {
...

// 方式1
getFlavorDimensionList().add('example_value')

// 方式2
flavorDimensions "example_value"
}

两种方式选择一种即可,方式1有代码补全提示,方式2没有。



  • 创建productFlavor

在app包下的build.gradle中的android闭包下,创建productFlavors,代码如下:


android {
...

productFlavors {
// 原始渠道
origin{
// 这里的值与前面flavorDimensions设置的值保持一致
dimension 'example_value'
}

// 示例渠道
exampleFlavor {
// 这里的值与前面flavorDimensions设置的值保持一致
dimension 'example_value'
}
}
}

网上找到的相关文章都说productFlavor中需要配置dimension,但是在尝试的过程中发现,如果只添加了一个flavorDimensions,那么productFlavor中的dimension可以不用特别声明(我的gradle版本为7.6,AGP为7.4.1)。


构建完后可以在Build Variants中看到已配置的变体,如图:


屏幕截图(8).png

渠道包参数配置


打渠道包时,根据需求可能会需要配置不同参数,例如App的名称、图标、版本信息,服务器地址等。



  • 配置不同的签名信息

如果需要使用不同的签名文件,可以在app包下的build.gradle中的android闭包下配置signingConfigs,代码如下:


android {
signingConfigs {
origin {
keyAlias 'expampledemo'
keyPassword '123456'
storeFile file('ExampleDemo')
storePassword '123456'
}

exampleFlavor {
keyAlias 'exampledemoflavor'
keyPassword '123456'
storeFile file('ExampleDemoFlavor.jks')
storePassword '123456'
}
}

flavorDimensions "example_value"

productFlavors {
origin{
signingConfig signingConfigs.origin
}

exampleFlavor {
signingConfig signingConfigs.exampleFlavor
}
}
}

需要注意的是signingConfigs必须在productFlavors前面声明,否则构建会失败。



  • 配置包名、版本号

productFlavors中可以配置渠道包的包名、版本信息,代码如下:


android {
...

defaultConfig {
applicationId "com.chenyihong.exampledemo"
versionCode 1
versionName "1.0"
...
}

productFlavors {
origin{
...
}

exampleFlavor {
applicationId "com.chenyihong.exampledflavordemo"
versionCode 2
versionName "1.0.2-flavor"
}
}
}

origin渠道表示的是原始包,不进行额外配置,使用的就是defaultConfig中声明的包名以及版本号。


效果如图:


origin


1676109942922.png


exampleFlavor


1676110092402.png



  • 配置BuildConfig,字符串资源

productFlavors中配置BuildConfig或者resValue,可以让同名字段,在打不同的渠道包时有不同的值,代码如下:


android {
...
productFlavors {
origin{
buildConfigField("String", "example_value", "\"origin server address\"")
resValue("string", "example_value", "origin tips")
}

exampleFlavor {
buildConfigField("String", "example_value", "\"flavor server address\"")
resValue("string", "example_value", "flavor tips")
}
}
}

配置完后重新构建一下项目,就可以通过BuildConfig.example_value以及getString(R.string.example_value)来使用配置的字段。


效果如图:


origin


1676110403151.png


exampleFlavor


1676110302147.png



  • 配置manifestPlaceholders

有些三方SDK,会在Manifest中配置meta-data,并且这些值跟包名大概率是绑定的,因此不同渠道包需要替换不同的值,代码如下:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
...
>

<meta-data
android:name="channel_value"
android:value="${channel_value}"/>

....
</application>
</manifest>

android {
...
productFlavors {
origin{
manifestPlaceholders = [channel_value: "origin channel"]
}

exampleFlavor {
manifestPlaceholders = [channel_value: "flavor channel"]
}
}
}

效果如图:


origin


1676109422577.png


exampleFlavor


1676109298513.png



  • 配置不同的依赖

不同渠道包可能会引用不同的三方SDK,配置了productFlavors后,可以在dependencies中区分依赖包,代码如下:


dependencies {
// origin 包依赖
originImplementation("com.google.code.gson:gson:2.10.1")

// exampleFlavor包依赖
exampleFlavorImplementation("com.google.android.gms:play-services-auth:20.4.1")
}

示例:


FlavorExampleActivity中同时导入Gson包和Google登录包,效果如下:


origin


1676108237739.png

exampleFlavor


1676108290585.png

  • 配置不同的资源

在app/src目录下,创建exampleFlavor文件夹,创建与main包下一样的资源文件夹,打渠道包时,相同目录下同名的文件会自动替换,可以通过这种方式来实现替换应用名称和应用图标。


1676111680651.png


效果如图:


Screenshot_20230211_183741.png

示例Demo


按照惯例,在示例Demo中添加了相关的演示代码。


ExampleDemo github


ExampleDemo gitee


作者:ChenYhong
链接:https://juejin.cn/post/7198806651562229816
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册