简介:该工具快速生成渠道包。它可以将一个包快速生成多个渠道包
github地址 : https://github.com/mcxiaoke/packer-ng-plugin
使用场景:
安卓app上线,需要创建各个市场和推广渠道的apk安装包。每个安装包携带对应的渠道信息。
基本所有安卓项目需要创建渠道包,而且上线时间越长,推广渠道会越来越多,时有更新,同时可能还会有创建马甲包的需求。在实际中一次上线可能会创建数十个渠道包。所以使用一套方便、稳定的打包流程,是非常有必要的。尤其体现在打包时间,安装包稳定性方面。
创建多渠道方法:
方案一:在安卓项目studio编译器gradle文件中配置flavors.根据 flavors信息给每个apk包配置对应的渠道信息。生成Apk包再进行加固和签名,这种方法是在编译期将渠道文件写在buildconfig文件中,不受加固影响。但是它需要studio编译器生成N个渠道包,再将N个渠道包加固。studio和加固工具都不适合一次性处理过多apk文件,所以需要分批处理,这就会导致手动操作频繁和工作时间过长,容易出错也耗时过多。
方案二:使用打包工具(packer-ng-plugin)生成渠道包。先由studio编译器生成release包,再用360加固宝加固(不使用它的自动签名和签名校验),然后进行签名和验证,最后由该工具生成N个渠道包。这种流程单 一 ,始终是操作一个apk文件,相比方案一更好。无论是操作流程还是打包时间都是占有绝对优势的。
如何使用该工具?
进入github地址 : https://github.com/mcxiaoke/packer-ng-plugin
步骤一:在android项目中集成读取渠道的库。
修改项目配置
// build.gradle
buildscript {
dependencies{
classpath 'com.mcxiaoke.packer-ng:plugin:2.0.1'
}
}
修改模块配置
apply plugin: 'packer'
// build.gradle
dependencies {
compile 'com.mcxiaoke.packer-ng:helper:2.0.1'
}
步骤二:生成渠道包。
该库提供了多种方法生成渠道包,一种是在Gradle中生成,另一种是使用脚本打包工具packer-ng-2.0.1.jar来创建渠道包。由于安卓apk需加固,加固后会破坏渠道信息,所以实际中都是将加固后的apk文件再添加渠道信息。所以个人认为通过gradle来创建渠道包是不合适的,这就需要选择脚本打包工具来实现打包。这里,我就只讲脚本打包工具的使用。
鉴于安卓apk都需要加固的情况,同时现有的加固工具(我用的是360加固宝)会破坏签名文件,会让渠道信息丢失;加固Apk的过程也是需要时间的,尤其是加固数十个apk的时候,其加固时间是不可忽视。
2.1 脚本打包
项目提供的Java脚本打包,Jar位于本项目的 tools
目录,请使用最新版,以下用 packer-ng
指代 java -jar tools/packer-ng-2.0.1.jar
,下面是几个示例。
- 参数说明:
packer-ng - 表示 java -jar packer-ng-2.0.1.jar
channels.txt - 替换成你的渠道列表文件的实际路径
build/archives - 替换成你指定的渠道包的输出路径
app.apk - 替换成你要打渠道包的APK文件的实际路径
运行cmd程序,进入该工具的目录下,并将已经加固好的Apk放至该目录,然后执行下面的命令(下面使用的是相对路径,自己根据实际需要来编写对应的命令)。
- 直接指定渠道列表打包:
packer-ng generate --channels=ch1,ch2,ch3 --output=build/archives app.apk
- 指定渠道列表文件打包:
packer-ng generate --channels=@channels.txt --output=build/archives app.apk
上述命令都是相对路径,也可以写绝对路径,如下:
例: java -jar packer-ng-2.0.1.jar generate --channels=@D:\channelsFile\channels.txt --output=D:\ouputApk D:\apk\app.apk
效果都是一样的。
channels.txt的内容示例如下:
备注:
1.上述两行是实际打包中所需要用的最关键的两条语句。channels后面指定了多少个渠道信息,就会打多少个渠道包。以--channels=ch1,ch2,ch3为例表示需要打三个包,对应的Apk识别到的渠道信息分别就是ch1 ch2 ch3. 而--channels=@channels.txt表示会读取channels.txt的渠道信息,以换行符为分隔,每一行的字符串就是一个渠道信息,有多少行就会创建多少个渠道包(空字符串默认过滤)。
2.输出渠道包的文件名,有一定的规则,规则是由packer-ng-2.0.1.jar工具决定的。后述我讲到它的源码时请关注。在实际项目中,apk的文件名可能需要有我们自己的规则,例如各大应用市场,推广渠道等安装包是有特定名字的,这样方便后台管理。这个时候建议重新编译上述脚本工具,按照自己的规则生成文件名等。
3.该工具的核心代码其实是集成美团的多渠道打包项目中的代码。作者也标注出来了。作者是将美团多渠道打包的代码进行了精简和封装,便于开发者使用。可以用上面的命令比较轻松地创建多渠道包。
4.请注意V3签名。该库集成美团写入和读取渠道信息的代码没有及时更新。它现在并不支持V3签名的apk包写入渠道信息。美团打包库的代码已经更新,但该库还未更新最新代码。如果开发者使用V3签名apk(使用buildtools28及以上版本进行签名),那么这个apk文件被该库创建渠道包后,创建的渠道包如果安装在安卓9.0及以上系统上,会出现报错,安装不上,其它版本系统可以正常安装和正常读取渠道信息。这跟安卓9.0系统验证签名有关。
5.设置渠道信息注意事项。在设置渠道信息时(
channels.txt文件的内容),请不要使用特殊字符,例如“* ? |”等,如果设置了有这些特殊字符,会将其替换成"_"符号。该工具替换特殊字符的源码如下,可以根据如下替换规则来避免被替换了。如果开发者需要有自己的命名规则,可以重新编译该工具,自行修改。
读取
channels.txt文件中的渠道信息的源码如下:
public static Set<String> parseChannels(final File file) throws IOException {
final List<String> channels = new ArrayList<>();
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
String parts[] = line.split("#");
if (parts.length > 0) {
final String ch = parts[0].trim();
if (ch.length() > 0) {
channels.add(ch);
}
}
}
br.close();
fr.close();
return escape(channels);
}
替换渠道特殊字符规则如下:
public static Set<String> escape(Collection<String> cs) {
// filter invalid chars for filename
Pattern p = Pattern.compile("[\\\\/:*?\"'<>|]");
Set<String> set = new HashSet<>();
for (String s : cs) {
set.add(p.matcher(s).replaceAll("_"));
}
return set;
}
- 验证渠道信息:
packer-ng verify app.apk
- java -jar packer-ng-2.0.1.jar verify build/archives/5.apk
- 验证结果如下:
- 运行命令查看帮助
java -jar tools/packer-ng-2.0.1.jar --help