对于app运营来说,通常需要我们的APP统计在各大应用市场的下载和具体使用情况,这个时候我们就需要引入友盟统计或者其他第三方统计,包括各个市场相对应的包,渠道一多,打包就慢了,所以Walle快速打包诞生了!!
传统的渠道配置方式是在AndroidManifest.xml接入配置
<meta-data android:value="YOUR_APP_KEY" android:name="UMENG_APPKEY"/>
<meta-data android:value="Channel ID" android:name="UMENG_CHANNEL"/>
然后在配置文件build.gradle里面配置productFlavor来实现多渠道打包,这样做,能多渠道打包,但是效率并不高。其实如果我们能传入渠道ID,那么自然就能统计到相关信息了,因此友盟提供了新的接入方式:
MConfigure.init(Context context, String appkey, String channel, int deviceType, String pushSecret)
这时候我们可以将之前AndroidManifest.xml
中的channelId
配置相关的<meta-data>
删除,只需要提供channel即可,然后就可以通过美团Walle或者其他方式来获取到这个channel即可。
下面提供美团Walle接入步骤,主要有两种,一种是插件方式、一种是命令行模式
插件方式:
1.接入之前需要我们有自己的签名
buildTypes {
debug {
//获取打包时间
buildConfigField("String", "buildTime", "\""+new Date().format("yyyy/MM/dd HH:mm:ss")+"\"")
minifyEnabled false
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-android.txt'
}
release {
buildConfigField("String", "buildTime", "\""+new Date().format("yyyy/MM/dd HH:mm:ss")+"\"")
minifyEnabled false
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-android.txt'
}
}
signingConfigs {
debug {
storeFile file("./keystore/fanli.keystore")
storePassword 'fanli'
keyAlias 'fanli.keystore'
keyPassword 'fanli2222'
}
release {
storeFile file("./keystore/fanli.keystore")
storePassword 'fanli'
keyAlias 'fanli.keystore'
keyPassword 'fanli2222'
}
}
2.在项目的根目录 build.gradle
文件中添加Walle Gradle插件的依赖
dependencies {
classpath 'com.meituan.android.walle:plugin:1.1.6'
}
3.在当前App的 build.gradle
文件中apply这个插件,并添加上用于读取渠道号的架包
apply plugin: 'walle'
dependencies {
compile 'com.meituan.android.walle:library:1.1.6'
}
4.在当前App的 build.gradle中配置Walle
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}
配置项具体解释:
channelFile:包含渠道配置信息的文件路径,示例 https://github.com/Meituan-Dianping/walle/blob/master/app/channel
apkOutputFolder:指定渠道包的输出路径, 默认值为new File("${project.buildDir}/outputs/apk")
apkFileNameFormat:定制渠道包的APK的文件名称, 默认值为'${appName}-${buildType}-${channel}.apk'
可使用以下变量:
projectName - 项目名字
appName - App模块名字
packageName - applicationId (App包名packageName)
buildType - buildType (release/debug等)
channel - channel名称 (对应渠道打包中的渠道名字)
versionName - versionName (显示用的版本号)
versionCode - versionCode (内部版本号)
buildTime - buildTime (编译构建日期时间)
fileSHA1 - fileSHA1 (最终APK文件的SHA1哈希值)
flavorName - 编译构建 productFlavors 名
5.读取渠道
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
6.上传渠道到友盟
UMConfigure.init(Context context, String appkey, String channel, int deviceType, String pushSecret);
我们需要进行多渠道打包的时候,只需要执行
./gradlew clean assembleReleaseChannels
即可来生成所有的渠道,有时候执行该命令,我们可能会遇到R.java文件丢失的问题,可以通过AS的clean
又能重新生成,这时候我们可以把上述命令中的clean去掉,变为通过命令./gradlew assembleReleaseChannels
生成
扩展:生成指定渠道包
生成单个渠道包: ./gradlew clean assembleReleaseChannels -PchannelList=meituan
生成多个渠道包: ./gradlew clean assembleReleaseChannels -PchannelList=meituan,dianping
命令行方式
1.下载walle-cli-all.jar文件
2.执行的相关命令
显示当前apk中的渠道和额外信息:java -jar walle-cli-all.jar show /Users/fanli/app/build/outputs/apk/fanli_walle.apk
java -jar walle-cli-all.jar put -c[渠道名] [apk路径]
java -jar walle-cli-all.jar put -c[渠道名] [apk路径] [生成的apk路径(可选)]
指定渠道列表
java -jar walle-cli-all.jar batch -c xiaomi,meizu,360 [apk路径]
路径不指定的情况下,默认在原apk包同目录下
Walle多渠道打包渠道丢失的问题
为了代码安全app在上线的时候都会选择给app加固,加固之后会出现渠道找不到的问题,官方有给出相关的解决方案360加固失效?
这里我使用了ProtectedApkResignerForWalle脚本来解决这个问题
需要注意的是:
1.生成一个不带签名的包,可以通过执行assembleRelease这个task或者通过工具栏上面的Build下面的Generated Signed Apk
2.将生成的apk通过360网页版进行加固(通过其提供的桌面工具加固的话会自动使用V1方式签名),然后下载下来加固之后的apk,比如叫:fanli.encrypted.apk
3.克隆https://github.com/Jay-Goo/ProtectedApkResignerForWalle.git,然后把步骤2中生成的fanli.encrypted.apk项目的根目录,并根据按照config.py文件中的注释改成自己项目配置
4.根据情况看是否需要更改之前写好的Channel文件
5.运行命令 python ApkResigner.py,即可自动生成所有渠道包。之后我们即可在该仓库的channels文件夹下看到生成的各种渠道包了
当然如果不用第三方打包可以看我另一篇文章android 多渠道打包不同的包名、应用名、应用图标