本章将介绍360多渠道打包方法
Android多渠道打包(一):基础多渠道打包
Android多渠道打包(二):友盟多渠道打包
Android多渠道打包(三):美团多渠道打包
Android多渠道打包(四):360多渠道打包
Android多渠道打包(五):360多渠道打包+
Android多渠道打包(六):maven&gradle
Android多渠道打包(七):系列总结及展望
这个打包方法是由奇虎360的工程师开源出来的,这位大神在github的id是seven456
利用的是Zip文件“可以添加comment(摘要)”的数据结构特点,在文件的末尾写入任意数据,而不用重新解压zip文件(apk文件就是zip文件格式);所以该工具不需要对apk文件解压缩和重新签名即可完成多渠道自动打包,高效速度快,无兼容性问题;
/*关键代码*/
public static void main(String[] args) throws Exception {
// 写入渠道号
// args = "-path D:/111.apk -outdir D:/111/ -contents googleplay;m360; -password 12345678".split(" ");
// 查看工具程序版本号
// args = "-version".split(" ");
// 读取渠道号
// args = "-path D:/111_m360.apk -password 12345678".split(" ");
long time = System.currentTimeMillis();
String cmdPath = "-path";
String cmdOutdir = "-outdir";
String cmdContents = "-contents";
String cmdPassword = "-password";
String cmdVersion = "-version";
String help = "用法:java -jar MCPTool.jar [" + cmdPath + "] [arg0] [" + cmdOutdir + "] [arg1] [" + cmdContents + "] [arg2] [" + cmdPassword + "] [arg3]"
+ "\n" + cmdPath + " APK文件路径"
+ "\n" + cmdOutdir + " 输出路径(可选),默认输出到APK文件同一级目录"
+ "\n" + cmdContents + " 写入内容集合,多个内容之间用“;”分割(linux平台请在“;”前加“\\”转义符),如:googleplay;m360; 当没有" + cmdContents + "”参数时输出已有文件中的contents"
+ "\n" + cmdPassword + " 加密密钥(可选),长度8位以上,如果没有该参数,不加密"
+ "\n" + cmdVersion + " 显示MCPTool版本号"
+ "\n例如:"
+ "\n写入:java -jar MCPTool.jar -path D:/test.apk -outdir ./ -contents googleplay;m360; -password 12345678"
+ "\n读取:java -jar MCPTool.jar -path D:/test.apk -password 12345678";
if (args.length == 0 || args[0] == null || args[0].trim().length() == 0) {
System.out.println(help);
} else {
if (args.length > 0) {
if (args.length == 1 && cmdVersion.equals(args[0])) {
System.out.println("version: " + VERSION_1_1);
} else {
Map argsMap = new LinkedHashMap();
for (int i = 0; i < args.length; i += 2) {
if (i + 1 < args.length) {
if (args[i + 1].startsWith("-")) {
throw new IllegalStateException("args is error, help: \n" + help);
} else {
argsMap.put(args[i], args[i + 1]);
}
}
}
System.out.println("argsMap = " + argsMap);
File path = argsMap.containsKey(cmdPath) ? new File(argsMap.get(cmdPath)) : null;
String parent = path == null? null : (path.getParent() == null ? "./" : path.getParent());
File outdir = parent == null ? null : new File(argsMap.containsKey(cmdOutdir) ? argsMap.get(cmdOutdir) : parent);
String[] contents = argsMap.containsKey(cmdContents) ? argsMap.get(cmdContents).split(";") : null;
String password = argsMap.get(cmdPassword);
if (path != null) {
System.out.println("path: " + path);
System.out.println("outdir: " + outdir);
if (contents != null && contents.length > 0) {
System.out.println("contents: " + Arrays.toString(contents));
}
System.out.println("password: " + password);
if (contents == null || contents.length == 0) { // 读取数据;
System.out.println("content: " + readContent(path, password));
} else { // 写入数据;
String fileName = path.getName();
int dot = fileName.lastIndexOf(".");
String prefix = fileName.substring(0, dot);
String suffix = fileName.substring(dot);
for (String content : contents) {
File target = new File(outdir, prefix + "_" + content + suffix);
if (nioTransferCopy(path, target)) {
write(target, content, password);
}
}
}
}
}
}
}
System.out.println("time:" + (System.currentTimeMillis() - time));
}
}
1、命令行使用说明:
用法:java -jar MCPTool.jar [-path] [arg] [-contents] [arg] [-password] [arg]
-path APK文件路径
-outdir 输出路径(可选),默认输出到APK文件同一目录
-contents 写入内容集合,多个内容之间用“;”分割,如:googleplay;m360; 当没有“-contents”参数时输出已有文件中的content
-password 加密密钥(可选),长度8位以上,如果没有该参数,不加密
-version 显示版本号
例如:
写入:
java -jar MCPTool.jar -path D:/test.apk -outdir ./ -contents googleplay;m360; -password 12345678
读取:
java -jar MCPTool.jar -path D:/test.apk -password 12345678
2、Android代码中读取写入的渠道号:
导入MCPTool.jar中的MCPTool类,MCPTool.getChannelId(context, mcptoolPassword, defValue)读出写入的渠道号;
3、jenkins、hudson、ant使用说明:
请看MultiChannelPackageTool\build-ant\MCPTool\build.xml文件;
4、Windows下bat脚本运行说明:
拖拽文件即可完成多渠道打包:MultiChannelPackageTool\build-ant\MCPTool\MCPTool.bat;
拖拽文件检查渠道号是否写入成功:MultiChannelPackageTool\build-ant\MCPTool\MCPTool-check.bat;
/**
* Android平台读取渠道号
* @param context Android中的android.content.Context对象
* @param mcptoolPassword mcptool解密密钥
* @param defValue 读取不到时用该值作为默认值
* @return
*/
public static String getChannelId(Object context, String mcptoolPassword, String defValue) {
String content = MCPTool.readContent(new File(getPackageCodePath(context)), mcptoolPassword);
return content == null || content.length() == 0 ? defValue : content;
}
String channelId = MCPTool.getChannelId(context,password,default);
没有解压缩、压缩、重签名,没有兼容性问题,速度最快;写入的渠道号数据支持加密,安全可靠;
由于速度极快,我还可以作为服务器端下载apk时动态写入“特定数据”,用户下载到apk后安装启动,读取“特定数据”完成特定的操作;
如:加好友功能,下载前写入用户ID,用户下载后启动apk,读取写入的用户ID,完成加好友操作,用户体验大大提升,没有断裂感;
当然,也可以写入JSON数据,想做什么就做什么;
seven456:MultiChannelPackageTool