现在的android有着广泛的应用市场,相对应的渠道也可以说是多种多样,为了方便app更好的推广,运营同学就需要我们支持下数据采集,才能制定后续流程~
题外话:其实渠道统计不仅仅局限于应用市场,在现实生活中我们可以把每一种推广方式也看做是一个渠道,比如:通过人拉人的方式去推广,官网上推广,百度推广等。
随着渠道越来越多,为了运营更好的推广,有时候一次也会打成百的安装包,有的打包方式可能会造成半天或者一天啥也干不了,当然也有分分钟完成打包的方式…
使用美团多渠道打包
方式,10秒轻松打完上百渠道安装包
- 基础认知
- 前情提要
- 渠道配置
- 渠道打包
- 打包区别
- 原始、友盟多渠道打包
- 美团多渠道打包
- 关于项目实战的一些经验
- 渠道信息
小伙,每天进步一点点,后面会发现迈了一大步,不知不觉都过去快3年咯 ~
基础认知
什么是多渠道包?
渠道包就是要在安装包中添加渠道信息,也就是channel
,对应不同的渠道,例如:小米市场、360市场、应用宝市场等
如何声明一个渠道?它的本质实现是什么?
一般都是在 AndroidManifest
通过meta-data
标签声明渠道信息
,很多时候涉及的多渠道信息会放在build.gradle
中(如:通过原始方式进行多渠道分包、打包)
AndroidManifest
示例
<meta-data
android:name="CHANNEL_ID"
android:value="android" />
多渠道是如何实现分渠道的?
一般多渠道有俩种实现方式
- 动态替换
meta-data
中的value
值;如将上方中value
中的android
替换为huawei
<meta-data
android:name="CHANNEL_ID"
android:value="huawei" />
- 没有在
AndroidManifest
中通过meta-data
声明任何渠道信息,而是通过三方工具或三方平台打多渠道包时,整体插入meta-data内的渠道信息
为什么要提供多渠道包?
我们要在安装包中添加不同的标识,应用在请求网络的时候携带渠道信息,方便后台做运营统计
(这就是添加渠道信息的用处)
前情提要
如果想要观测不同渠道的应用数据,那么渠道分包是一个基础,其中主要涉及到俩部分
- 分渠道包
因为我分渠道的方式使用的是原始+部分Umeng多渠道分包
方式,所以有心人会发现部分Umeng
渠道统计也会进行部分一样的配置 - 打渠道包
这里使用的打包方式是最原始的AndroidStudio自带的一种打包
方式,虽然看起来方便,但是效率很低
,往往在渠道多的情况下,你会发现2分钟能办完的事儿,往往消耗几十分钟或者几个小时
~
渠道配置
这里采用的多渠道配置方式,其实早期是基于友盟方式做处理的
第一步:AndroidMainfest
(清单文件)中的application
内添加
<- 这里是方便Umeng的渠道统计,进行配置 UMENG_CHANNEL 不可改变不然无法识别 ->
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
示例:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dow.loadingview">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
</application>
</manifest>
第二步: build(app)
中,android标签
内添加渠道名
注意: 如果是数字开头是不行的!需要添加下划线!
- 公共配置
//打包相关配置
buildTypes {
debug {
// 不用管- - shrinkResources true // 移除无用的resource文件
minifyEnabled false //不启用混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro',
'proguard-fresco.pro'
}
release {
//不用管- - shrinkResources true // 移除无用的resource文件
minifyEnabled false //不启用混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
主要有以下是俩种渠道配置方式
- 方式一:
uc的方式添加渠道
productFlavors{
uc {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"]
}
_360 {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]
}
baidu{
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
}
}
- 方式二:
productFlavors方式添加渠道
productFlavors{
default_channel{}
wandoujia{}
yingyongbao{}
xiaomi{}
huawei{}
jifeng{}
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [ UMENG_CHANNEL_VALUE:name ]
}
渠道打包
在此时,我们的
渠道配置
已经做完,可以进入打包阶段,但需注意你既然要打渠道包,必然是要上appStore
的,这里就涉及到了一个签名
的问题,你可以通过生成 keystore、jks 签名证书进行学习,不然你打出的也是没有签名的包,用户是无法安装的!
这里采用的打包工具是AndroidStudio内的Gradle打包方式,相比别的打包方式会慢挺多的
AndroidStudio
内的Gradle打包
最终结果:没签名的包状态
最终结果:签名的包状态
打包区别
在我目前的从业经历中,对于多渠道打包方面的经验主要有渠道配置和俩种渠道打包的方式
原始、友盟多渠道打包
原: 直接在清单文件
中定义meta-data
标签设置渠道值,读取对应值当做渠道id
↓
现:使用友盟方式分渠道
,原始方式打包
一般来讲,这个渠道的标识会放在AndroidManifest
的Application
的一个meta-data
中;然后就可以通过对用方法获取对应的渠道信息(方法位于篇尾)
优:配置简单,使用方便
缺:渠道多的时候,效率较低
美团多渠道打包
在 AndroidManifest
配置基础包即可,无需 build.app
内进行任何配置,主要依赖Python写的工具
优:配置之后,使用方便,效率很高
缺:三方工具,安全性方面可能需要稍微考虑下
关于项目实战的一些经验
我们现在打的签名包,大多都会进行加固,然后分渠道,涉及先后顺序
- 先根据签名包打出多渠道包,然后挨个进行加固
- 先加固签名包,然后打出多渠道包
明眼人一看,肯定选第二个,那么你是对的!因为亲测之后,加固效果依旧在,同时渠道依旧可以正常识别 ~
渠道信息
以备不时之需 - 附赠一个小方法(用于获取当前apk的渠道 - 网上找的,没有亲测 - -~)
/**
* 获取渠道名
* @param context 此处习惯性的设置为activity,实际上context就可以
* @return 如果没有获取成功,那么返回值为空
*/
public String getChannelName() {
if (this.mContext == null) {
return null;
}
String channelName = null;
try {
PackageManager packageManager = this.mContext.getPackageManager();
if (packageManager != null) {
//注意此处为ApplicationInfo 而不是 ActivityInfo,因为友盟设置的meta-data是在application标签中,而不是某activity标签中,所以用ApplicationInfo
ApplicationInfo applicationInfo = packageManager.
getApplicationInfo(this.mContext.getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo != null) {
if (applicationInfo.metaData != null) {
channelName = String.valueOf(applicationInfo.metaData.get("UMENG_CHANNEL"));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return channelName;
}