Android多渠道打包【友盟方式详细讲解版】
开发环境:
Mac OS 15.0.1
Android Studio Jellyfish | 2023.3.1 Patch 2
废话不讲,不浪费大家时间,每步骤后面有解释,直接开始上手干
第一步: 在程序的清单文件【app/src/main/AndroidManifest.xml】配置如下节点内容:
<application
......
>
<activity
.......... />
<!-- 添加友盟支持 -->
<meta-data
android:name="APP_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
</application>
注意: 该<meta-data …/>在application大节点下是和activity、provider、receiver等节点是齐平地位,不要放错位置了。其中这里的${UMENG_CHANNEL_VALUE}是一个Gradle变量,在打包时会根据实际配置替换成具体的渠道值,俗称占位符【打单包可独立配置】,而android:name="APP_CHANNEL"这个名字是为了到时候取渠道打包的字段名字。看下文获取打包渠道名就明白这些字段的含义,当然你可以对应改掉这2个值名字,其中它通过android:name和android:value属性来定义一个名称-值对,但这只是在XML文件中的静态配置。
和常规的键值对(Key-Value Map) 在内存中动态地存储和检索键值对很类似,但俩者是不同。
第二步: 在项目的主app/build.gradle的文件中进行如下配置:
buildTypes {
debug {
minifyEnabled false // debug不开启混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
applicationVariants.all { variant ->
resValue "string", "app_name", "替换成你的应用名"
}
}
release {
minifyEnabled true // release开启混淆 【开启混淆记得在app/proguard-rules.pro添加项目库的混淆规则,具体规则看库的说明要求】
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
applicationVariants.all { variant ->
resValue "string", "app_name", "替换成你的应用名"
}
}
}
// 友盟多渠道打包配置
flavorDimensions "channel"
productFlavors {
toutiao {
manifestPlaceholders = [CHANNEL_VALUE: "toutiao"]
dimension "channel"
}
huawei {
manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
dimension "channel"
}
oppo {
manifestPlaceholders = [CHANNEL_VALUE: "oppo"]
dimension "channel"
}
vivo {
manifestPlaceholders = [CHANNEL_VALUE: "vivo"]
dimension "channel"
}
xiaomi {
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
dimension "channel"
}
yingyongbao {
manifestPlaceholders = [CHANNEL_VALUE: "yingyongbao"]
dimension "channel"
}
common {
manifestPlaceholders = [CHANNEL_VALUE: "common"]
dimension "channel"
}
kuaishou {
manifestPlaceholders = [CHANNEL_VALUE: "kuaishou"]
dimension "channel"
}
baidu {
manifestPlaceholders = [CHANNEL_VALUE: "baidu"]
dimension "channel"
}
safe360 {
manifestPlaceholders = [CHANNEL_VALUE: "safe360"]
dimension "channel"
}
//添加荣耀的渠道包
honor {
manifestPlaceholders = [CHANNEL_VALUE: "honor"]
dimension "channel"
}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
这里可以继续类似添加,比如我追加添加//添加荣耀的渠道包的方式。注意,打包之前记得签名,使用Android Studio自带签名【也可以直接在app/build.gradle配置】【具体操作各位自行找资料,很简单】,也可直接在app/build.gradle配置大致内容如下【注意不要放错位置】:
android {
signingConfigs {
debug {
storeFile file('你的签名文件【可带具体路径】.jks')
storePassword '12345600' //
keyAlias 'key00'
keyPassword '12345600'
// V1 和 V2签名,开启【可开启其中一个】
v1SigningEnabled true
v2SigningEnabled true
}
release {
storeFile file('你的签名文件【可带具体路径】.jks')
storePassword '12345600'
keyAlias 'key00'
keyPassword '12345600'
v1SigningEnabled true
v2SigningEnabled true
}
}
namespace '你的应用包名'
compileSdk 34
......
解释:
storeFile file(‘你的签名文件【可带具体路径】.jks’)
------ 指定用于签名的JAR签名密钥库(JKS)文件路径。你需要将’你的签名文件【可带具体路径】.jks替换为实际的.jks文件路径,例如file(‘path/to/your/signing-key.jks’)。
storePassword ‘12345600’
------ 指定JKS文件的存储密码。这个密码用于解锁密钥库文件,确保其安全性。请根据实际情况修改为正确的密码。
keyAlias ‘key00’
------ 指定密钥库中的别名(alias)。每个密钥库可以包含多个密钥对,别名用于标识特定的密钥对。请根据实际情况修改为正确的别名。
keyPassword ‘12345600’
------ 指定密钥对的密码。这个密码用于解锁具体的密钥对,确保其安全性。请根据实际情况修改为正确的密码。
v1SigningEnabled true
------ 启用V1签名方案(Jar Signature)。V1签名是传统的签名方式,适用于较旧版本的Android系统。设置为true表示启用该签名方式。
v2SigningEnabled true
------ 启用V2签名方案(APK Signature Scheme v2)。V2签名是一种更安全、更高效的签名方式,适用于Android 7.0(API级别24)及以上版本。设置为true表示启用该签名方式。
注意事项:
安全性:请确保storePassword和keyPassword等敏感信息不要硬编码在公开的代码仓库中,建议使用环境变量或安全的构建工具来管理这些信息。
签名方案选择:通常建议同时启用V1和V2签名方案,以确保应用能在尽可能多的设备上正常安装和运行。
配置好了,记得同步
正常来说,你的项目没有错误一般是没有错误出现的。
以上配置完成,如何在Android Studio查看是否成功。【在左侧面板找到锤子似的的查看,没有的话就点击…找到这个图标如下图所示】
配置完成以后展开就是这样。
现在打一个单包【比如小米的发布包】,操作如下图所示。
等待
完成提示
点击locate就出现你刚刚打的小米包。现在对打包改造一下添加打包带名字版本号的便于自己打的包是哪个版本,在第二步里在项目的主app/build.gradle的文件中进行如下配置继续添加 applicationVariants.all { variant ->等等,内容如下:
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
// 就是在
// 为多渠道包,添加一个applicationVariants.all的闭包,在闭包中,通过variant.name获取当前渠道包名称,
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith(".apk")) {
def fileName = outputFile.name.replace(".apk", "_${defaultConfig.versionName}_${new Date().format("yyyyMMdd")}.apk")
outputFileName = fileName
}
}
}
再次同步,选中之前打包小米的debug版和release版,继续执行打包流程,执行结果分别如下:
如何获取打包渠道便于后端统计。写一个工具类.java的代码代码如下:
public class DeviceUtils {
//这里是获取自定义meta-data字段,比如在APP_CHANNEL
public static String getChannelId(Context context) {
String channelId = "default";
try {
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
channelId = appInfo.metaData.getString("APP_CHANNEL");
} catch (Exception e) {
e.printStackTrace();
}
return channelId;
}
}
前文说到在清单文件配置的<meta-data …>内容,其中APP_CHANNEL就是channelId获取标志。打个小米发布版测试是否获取成功。
MyLogUtils.d("渠道标识 channelFlag = "+DeviceUtils.getChannelId(context)) // 渠道标识
输出结果如下: