多渠道打包实践

Posted by one_cup on 2016-12-12

多渠道打包实践

项目要生成渠道包,调研发现有多重实现方式。
1.可以使用本身统计工具所提供的的打渠道包的方式。
2.使用第三方打包方案,这里有多种选择,可以采用最快的方式。
3.使用Gradle进行多渠道打包。
由于项目中有使用Tinker,选择使用Gradle进行多渠道打包。

配置

以TalkingData为例:
第一步:在Android的AndroidManifest.xml中添加:

1
2
3
4
<meta-data
android:name="TD_CHANNEL_ID"
android:value="${TD_CHANNEL_VALUE}" />

第二步:在Module的Gradle中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
defaultConfig {
//add this
manifestPlaceholders = [TD_CHANNEL_VALUE:"hbl"]
}
//添加渠道
productFlavors {
_360 {}
baidu {}
tencent{}
hbl{}
}
//根据渠道设置不同的渠道id
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [TD_CHANNEL_VALUE: name]
}

第三步:执行Gradle中assembleRelease这个Task,会自动生成不同的渠道包,需要修改在生成release的包名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//设置生成apk的文件名
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 输出apk名称为app_v版本号_渠道号_sigin.apk
def fileName = "app_v${defaultConfig.versionName}_${variant.productFlavors[0].name}_sigin.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
```
执行完以上三步之后就可以在output中看到生成的不同渠道包,其实打渠道包的本质就是在编译期动态改变AndroidManifest.xml中的某一个字段。功能是这个功能,但是实现方式有很多,如果没有其他的特别要求的话,就是简单的打渠道包,那么当然要使用最快速的方式。
## 关于更新和Tinker ##
由于使用渠道包,那么在强制更新的时候得根据你当前使用的渠道,去下载想要得到对应的渠道包,Tinker的原理也是一样的,怎么才能下到对应的渠道包那?
首先必须得知道当前的包是哪个渠道的,我们可以通过代码去获得AndroidManifest.xml中配置的渠道ID
```java
try {
ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA);
String value = appInfo.metaData.getString("TD_CHANNEL_ID");
Log.d("Tag", " TD_CHANNEL_ID : " + value);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}

这个是在元素下配置元素。
获取到对应的渠道id之后,就可以在请求更新包,补丁包的时候将对应的渠道id拼到相应的请求网址上,同时,后台放置所有的渠道包,约定包名,这样在请求的时候会根据渠道id请求下载对应的渠道包或补丁包。