Android多渠道打包(三):美团多渠道打包
来源:互联网 发布:网络热点事件2017 编辑:程序博客网 时间:2024/04/30 14:25
本章将介绍美团多渠道打包方法
Android多渠道打包(一):基础多渠道打包
Android多渠道打包(二):友盟多渠道打包
Android多渠道打包(三):美团多渠道打包
Android多渠道打包(四):360多渠道打包
Android多渠道打包(五):360多渠道打包+
Android多渠道打包(六):maven&gradle
Android多渠道打包(七):系列总结及展望
来源
本方法为美团点评技术团队2014.6.13日在《美团Android自动化之旅—生成渠道包》的文章中放出。
原理
将apk解包,然后在META-INF目录下创建一个以渠道号为文件名的空文件,再讲apk压缩,通过读取以渠道号为文件名的空文件的文件名来获取渠道号。
实现
- 方法1: 使用python为apk文件添加渠道空文件
import zipfilezipped = zipfile.ZipFile(your_apk, 'a', zipfile.ZIP_DEFLATED) empty_channel_file = "META-INF/channel_{channel}".format(channel=your_channel)zipped.write(your_empty_file, empty_channel_file
* 方法2: 使用java代码export出jar文件进行脚本打包
java代码如下(引用自魏成林)
public class Tool { private static final String CHANNEL_PREFIX = "/META-INF/"; private static final String CHANNEL_PATH_MATCHER = "regex:/META-INF/mtchannel_[0-9a-zA-Z]{1,5}"; private static String source_path; private static final String channel_file_name = "channel_list.txt"; private static final String channel_flag = "channel_"; public static void main(String[] args) throws Exception { if (args.length <= 0) { System.out.println("请输入文件路径作为参数"); return; } final String source_apk_path = args[0]; int last_index = source_apk_path.lastIndexOf("/") + 1; source_path = source_apk_path.substring(0, last_index); final String source_apk_name = source_apk_path.substring(last_index, source_apk_path.length()); System.out.println("包路径:" + source_path); System.out.println("文件名:" + source_apk_name); ArrayList<String> channel_list = getChannelList(source_path + channel_file_name); final String last_name = ".apk"; for (int i = 0; i < channel_list.size(); i++) { final String new_apk_path = source_path + source_apk_name.substring(0, source_apk_name.length() - last_name.length()) // + "_" + channel_list.get(i) + last_name; copyFile(source_apk_path, new_apk_path); changeChannel(new_apk_path, channel_flag + channel_list.get(i)); } } /** * 修改渠道号,原理是在apk的META-INF下新建一个文件名为渠道号的文件 */ public static boolean changeChannel(final String zipFilename, final String channel) { try (FileSystem zipfs = createZipFileSystem(zipFilename, false)) { final Path root = zipfs.getPath("/META-INF/"); ChannelFileVisitor visitor = new ChannelFileVisitor(); Files.walkFileTree(root, visitor); Path existChannel = visitor.getChannelFile(); Path newChannel = zipfs.getPath(CHANNEL_PREFIX + channel); if (existChannel != null) { Files.move(existChannel, newChannel, StandardCopyOption.ATOMIC_MOVE); } else { Files.createFile(newChannel); } return true; } catch (IOException e) { System.out.println("添加渠道号失败:" + channel); e.printStackTrace(); } return false; } private static FileSystem createZipFileSystem(String zipFilename, boolean create) throws IOException { final Path path = Paths.get(zipFilename); final URI uri = URI.create("jar:file:" + path.toUri().getPath()); final Map<String, String> env = new HashMap<>(); if (create) { env.put("create", "true"); } return FileSystems.newFileSystem(uri, env); } private static class ChannelFileVisitor extends SimpleFileVisitor<Path> { private Path channelFile; private PathMatcher matcher = FileSystems.getDefault().getPathMatcher(CHANNEL_PATH_MATCHER); public Path getChannelFile() { return channelFile; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (matcher.matches(file)) { channelFile = file; return FileVisitResult.TERMINATE; } else { return FileVisitResult.CONTINUE; } } } /** 得到渠道列表 */ private static ArrayList<String> getChannelList(String filePath) { ArrayList<String> channel_list = new ArrayList<String>(); try { String encoding = "UTF-8"; File file = new File(filePath); if (file.isFile() && file.exists()) { // 判断文件是否存在 InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式 BufferedReader bufferedReader = new BufferedReader(read); String lineTxt = null; while ((lineTxt = bufferedReader.readLine()) != null) { // System.out.println(lineTxt); if (lineTxt != null && lineTxt.length() > 0) { channel_list.add(lineTxt); } } read.close(); } else { System.out.println("找不到指定的文件"); } } catch (Exception e) { System.out.println("读取文件内容出错"); e.printStackTrace(); } return channel_list; } /** 复制文件 */ private static void copyFile(final String source_file_path, final String target_file_path) throws IOException { File sourceFile = new File(source_file_path); File targetFile = new File(target_file_path); BufferedInputStream inBuff = null; BufferedOutputStream outBuff = null; try { // 新建文件输入流并对它进行缓冲 inBuff = new BufferedInputStream(new FileInputStream(sourceFile)); // 新建文件输出流并对它进行缓冲 outBuff = new BufferedOutputStream(new FileOutputStream(targetFile)); // 缓冲数组 byte[] b = new byte[1024 * 5]; int len; while ((len = inBuff.read(b)) != -1) { outBuff.write(b, 0, len); } // 刷新此缓冲的输出流 outBuff.flush(); } catch (Exception e) { System.out.println("复制文件失败:" + target_file_path); e.printStackTrace(); } finally { // 关闭流 if (inBuff != null) inBuff.close(); if (outBuff != null) outBuff.close(); } }}
将渠道号写入channel_list.text
channel_onechannel_twochannel_three
使用java命令脚本打包
java -jar tool.jar your.apk
- 在android代码中获取渠道id
public static String getChannel(Context context) { ApplicationInfo appinfo = context.getApplicationInfo(); String sourceDir = appinfo.sourceDir; String ret = ""; ZipFile zipfile = null; try { zipfile = new ZipFile(sourceDir); Enumeration<?> entries = zipfile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = ((ZipEntry) entries.nextElement()); String entryName = entry.getName(); if (entryName.startsWith("channel_")) { ret = entryName; break; } } } catch (IOException e) { e.printStackTrace(); } finally { if (zipfile != null) { try { zipfile.close(); } catch (IOException e) { e.printStackTrace(); } } } String[] split = ret.split("_"); if (split != null && split.length >= 2) { return ret.substring(split[0].length() + 1); } else { return ""; } }
优缺点
比友盟高效点,只有解压缩和压缩,没有签名,兼容性也比较好,但是读取渠道号需要解压缩apk,速度比较慢
引用
美团Android自动化之旅—生成渠道包
魏成林:分享一种最简单的Android打渠道包的方法
1 0
- Android多渠道打包(三):美团多渠道打包
- Android美团多渠道打包
- Android美团多渠道打包方式
- android 美团多渠道打包详解
- APK打包 (多渠道打包,美团打包)
- 美团多渠道打包记录
- 美团多渠道快速打包
- Android Studio 多渠道打包(三)
- Android多渠道打包汇总(六)—— 美团的多渠道打包方式
- Android 一站式打包(二)美团多渠道方案
- 【Android 进阶】美团的多渠道打包方式
- Android多渠道打包(一):基础多渠道打包
- Android多渠道打包(四):360多渠道打包
- Android多渠道打包(五):360多渠道打包+
- 美团多渠道打包方案初体验
- 美团多渠道打包原理以及使用
- 美团多渠道打包方案初体验
- 美团多渠道打包之实现篇
- LeetCode oj 404. Sum of Left Leaves (DFS||BFS)
- modelsim仿真环境的搭建
- 简单的将一个html(xml)文本中的img标签(图片)提取出来的方法
- 【C#版本详情回顾】C#4.0主要功能列表
- 改变滚动条式样
- Android多渠道打包(三):美团多渠道打包
- Perl中的正则表达式
- Atitit 判断判断一张图片是否包含另一张小图片
- 控件设置背景色 以及 QPushButton 隐藏边框
- 商城之商品列表
- HDU 1814 Peaceful Commission(2-SAT)
- hdu5521Meeting/2015acmicpc沈阳3号题(图论最短路)
- nyist 35 表达式求值
- 1.Nexus安装与配置