04-微信 Tinker 热补丁实践演进之路
2020-02-27 182浏览
- 1.微信Tinker热补丁实践演进之路 shwenzhang 张绍文 2016年9月
- 2.关于我 ———ABOUT ME 张绍文 毕业于哈尔滨工业大学 搜狗 手机输入法Android组 (2012.02~2013.07) 微信 基础优化组 (2013.07~2015.05) 基础组件组 (2015.06~至今) 长期负责 微信插件化,性能体验,质量监控,编译 微信网络组件,跨平台开发 目前负责 WeMobileDev公众号 终端质量运营平台 Tinker热补丁项目
- 3.目录 Contents 1 热补丁的两大流派 2 Tinker v1.0—牛刀小试 3 Tinker v2.0—自创功法 4 Tinker v3.0—修炼内功 5 Tinker v4.0—内外兼修 6 微信的开源之路
- 4.热补丁的两大流派 何为热补丁 可以让应用无需重新安装下能够自动更新 12小时 90%+ 32M 100K 随意调 试
- 5.热补丁的两大流派 两大流派 Native Java AndFix KKFix 热补丁技术哪家强? Qzone nuwa Tinker amigo robust rocooFix
- 6.热补丁的两大流派 微信设计目标 稳定性与兼容性 性能 易用性 微信数亿用户的 非补丁版本影响 简单易用 设备上稳定运行 补丁大小 完整支持 “高可用”的补丁框架
- 7.目录 Contents 1 热补丁的两大流派 2 Tinker v1.0—牛刀小试 3 Tinker v2.0—自创功法 4 Tinker v3.0—修炼内功 5 Tinker v4.0—内外兼修 6 微信的开源之路
- 8.Tinker V1.0—牛刀小试 v1.0-2015年9月 基于Qzone的classloader方案 Patch.dex Classes.dex wechat.class wechat.class 主要问题 Class resolved by unexpected DEX crash 解决思路 DexPathList Class插桩阻止类判别为preverify 安卓App热补丁动态修复技术介绍
- 9.Tinker V1.0—牛刀小试 V1.0-晴天霹雳 启动耗时报警 Art平台补丁后无法启动 static Boolean addFriendTipsShow = false
- 10.Tinker V1.0—牛刀小试 V1.0-Dalvik verify dexopt preverify no optimize verify+optimize at runtime DEX Opcode ODEX Opcode Optimization iget iget-quick iput iput-quick invoke-virtual invoke-virtual-quick inline, use byte offset, vtable for faster 0(n) ->0(1) 插桩方案 • 性能损耗 • Optimize full mode • hack preverify flag
- 11.Tinker V1.0—牛刀小试 V1.0-Art平台 机器码 字节码 0x01bc:iget-object v0, v9, Lcom/tencent/LauncherUI; com.tencent.LauncherUI.addFriendTipsShow //field@40469 >> 0x0204c05a:2a0a 0x0204c05c:f2c086a9 0x0204c060:f3bf8f5b 0x0204c064:f8d06820 cmp blt.w dmb ldr.w r2, #10 +3410) ish r6, [r0, #2080] 用时查找 内存地址错乱 在Dalvik平台,最终会通过field id 在Art平台,由于增加了Field, 导致 查找到正确的变量 整体内存地址错乱 static ImageView sightChangeImage;
- 12.Tinker V1.0—牛刀小试 V1.0-牛刀小试 “高可用”的补丁框架 稳定性与兼容性 性能 • 性能影响 • 补丁大小 易用性 • • 简单易用 完整支持 96.3% 五天成功率 -31% 启动耗时 800K 补丁包大小
- 13.目录 Contents 1 热补丁的两大流派 2 Tinker V1.0—牛刀小试 3 Tinker V2.0—自创功法 4 Tinker V3.0—修炼内功 5 Tinker V4.0—内外兼修 6 微信的开源之路
- 14.Tinker V2.0—自创功法 V2.0-2016年2月 基于全量合并方式 • Gradle Instant run • Buck exopackage Diff算法 • BsDiff • DexMerge • DexDiff Diff设计目标 • Diff结果小 • 占用内存小,合成速度快 • 支持新增、删除、修改class
- 15.Tinker V2.0—自创功法 V2.0-Dex格式 低内存、快速 每段处理,一次读写 引用修正 • index修正,排序校验 • offset修正,无序且互相引用 合法校验 四字节对齐、dexopt、dexoat校验https://source.android.com/devices/tech/dalvik/dex-format.html
- 16.Tinker V2.0—自创功法 V2.0-Diff方案 Index区域 a b 01 Del 2 c 02 d e >> a c d e f Add f(5) new.dex old.dex 结果 用例ID 1 2 3 4 原始Dex大小(KB) 新Dex大小(KB) 228.72 10617.16 12723.15 12744.78 624.76 10617.7 12723.2 12744.78 BSDiff(KB) 48.00 260.00 173.00 10570.00 DexDiff(KB) 1.64 7.64 1.56 5881 时间(ms) 95 7917 9517 8448 峰值内存(M) 3 26 32 39
- 17.Tinker V2.0—自创功法 V2.0-晴天霹雳 来自小米的Anr 来自华为的Crash
- 18.Tinker V2.0—自创功法 V2.0-厂商OTA的挑战 原因分析 01Dalvik:modtime/crc 02 Art : checksum/image_checksum/image_offset… 10M Dex Dalvik • • 10.91M 5S FingerPrint change?提供加载页 Art • • 35M 12S 分平台合成,在Art只合成与v1.0一致的小Dex
- 19.Tinker V2.0—自创功法 V2.0-厂商OTA的挑战 难点 Dalvik base.dex full-new.dex patch.dex small-art.dex • • • • • small class收集 ClassN处理 偏移如何修正 art.info的大小 有效性校验 Art.info 01 解决问题 02 03 Dalvik全量合成,解决了插桩带来的性能损耗 分平台合成,解决了全量合成方案占用rom体积过大 Art.info仅仅1-20K, 解决由于补丁包可能过大
- 20.Tinker V2.0—自创功法 V2.0-其他技术挑战 Android N Xposed Classloader DexDiff
- 21.Tinker V2.0—自创功法 V2.0-自创功法 “高可用”的补丁框架 稳定性与兼容性 性能 • 性能影响 • 补丁大小 易用性 • • 简单易用 完整支持 94.1% 五天成功率 -2% 启动耗时 10K 补丁包大小
- 22.目录 Contents 1 热补丁的两大流派 2 Tinker V1.0—牛刀小试 3 Tinker V2.0—自创功法 4 Tinker V3.0—修炼内功 5 Tinker V4.0—内外兼修 6 微信的开源之路
- 23.Tinker V3.0—修炼内功 V3.0-2016年4月 加载 什么类可以修改 合成 进程隔离与通知 一致性 异常熔断 版本一致性,代码一致性 出现异常情况,及时回退 监控回调 对加载与合成整个过程的监控回调 安全 补丁签名与合成结果校验
- 24.Tinker V3.0—修炼内功 V3.0-异常熔断 check patch Java Crash – load {try catch Throwable} --> onLoadException safe++ safe>= 3 no – patch {try catch Throwable} --> onPatchException yes Native/UnCaught Crash – 安全启动模式,单一进程连续三次无法启动,清除patch load patch Crash Protect start = 0 attatchBaseContext – 程序启动10s内多次Crash,清除patch – crash时Xposed判别,清除patch
- 25.Tinker V3.0—修炼内功 V3.0-监控回调 Load Report 补丁加载过程中的相关信息 • 加载结果/耗时 • 失败原因 • crash信息 Patch Report 补丁合成过程中的相关信息 • 加载结果/耗时 • 失败原因 • crash信息
- 26.Tinker V3.0—修炼内功 V3.0-一致性 01 一致性 02 进程一致性 不同的进程需要保证加载同一个版本的补丁 逻辑一致性 dex, library与资源应该同时成功,或者失败 逻辑一致性 进程一致性 641e634c5b old version old!=new dex exist and reflect ok main process library exist res exist and reflect ok new version 2c150d8560 patch upgrade patch process load dex ok check dex load other process load res ok
- 27.Tinker V3.0—修炼内功 V3.0-加载与合成 补丁加载 补丁如何加载,什么类可以修改,类如何隔离 补丁合成 补丁合成进程隔离,结果及时通知 patch load TinkerApplication main process patch process patch request patch listener patch service patch check dex recover patch process dex opt loader class patch retry patch recover restart process ApplicationLike result handle loadReporter result service patch result patchReporter
- 28.Tinker V3.0—修炼内功 V3.0-修炼内功 “高可用”的补丁框架 95.3% 96.3% 五天成功率 稳定性与兼容性 性能 • 性能影响 • 补丁大小 易用性 • • 简单易用 完整支持 request 发起请求 download 1.5% 2.5% v1.0 1. 运营商挟持 2. 下载失败 patch listener patch service patch result 1. 剩余空间少于100M 2. 版本校验失败 1. 读写失败 2. 校验失败 3. patch进程被杀 成功应用
- 29.目录 Contents 1 热补丁的两大流派 2 Tinker V1.0—牛刀小试 3 Tinker V2.0—自创功法 4 Tinker V3.0—修炼内功 5 Tinker V4.0—内外兼修 6 微信的开源之路
- 30.Tinker V4.0—内外兼修 V4.0-Library处理 核心问题 01 02 多abi获取不准备,反射出问题 32位与64位问题 尽量少的hook • LoadLibraryFromTinker("assets/x86", "stlport_shared"); • LoadLibrary("stlport_shared");
- 31.Tinker V4.0—内外兼修 V4.0-资源处理 Add asset path? 预埋entry count • • • 编译强耦合 影响基础版本 无法随心所欲 全量替换 • • Atlas或者携程的插件化框架 Gradle-instant run
- 32.Tinker V4.0—内外兼修 V4.0-异常情况 Transition动画 ResId无法新增、删除,可能出现Res not found Notification ResId无法新增、删除,可能出现Res not found Shortcut ResId无法新增、删除,可能会变成默认图标 Assets 读取source apk方式无法修改
- 33.Tinker V4.0—内外兼修 V4.0-资源包生成 1. 将base.apk解压 空间 36M->83M 2. 将补丁包中修改、新增资源覆盖 峰值占用:83+4+36-16=107M 文件数 :5492个 4M 3. 排除删除以及Dex、Lib等文件 16M 时间 一次解压一次压缩:42S 4. 重新Zip压缩 资源包 无法合成后资源包的md5 解压 替换 >> 替换 写 压缩
- 34.Tinker V4.0—内外兼修 资源处理-资源包生成 文件头 源数据 … … 文件头 源数据 目录源数据 目录源数据 … 目录结束 目录结束 result.apk base.apk 空间 文件头 源数据 … 目录源数据 … 目录结束 patch.apk 峰值占用:107M --> 4+36-16=24M 文件数 : 5492个 --> 2个 时间 一次读写:42S --> 3S 资源包 合成后资源包的md5 剔除time/extra/comment随机因子
- 35.Tinker V4.0—内外兼修 资源处理-资源包校验 20% 合成后md5校验不通过? 应用市场增量算法 • • • 不保证entry顺序 不保证压缩流大小 只保证最终解压后的每个文件 替代方式 • • 校验resources.arsc md5 异步校验核心文件
- 36.Tinker V4.0—内外兼修 V4.0-编译目标 简单易用 • 只要输入一个旧的基础包,即可生成补丁包 • proguard • mainDex • 日志与校验 灵活控制 • 可通过pattern灵活控制需要的内容 • 版本管理 减少补丁包 • applyMapping • appyResourceMapping • force jumbo • 7zip …
- 37.Tinker V4.0—内外兼修 V4.0-内外兼修 “高可用”的补丁框架 稳定性与兼容性 性能 性能 • 性能影响 • Dalvik占rom体积 • 补丁大小 • 额外的合成过程,降低成功率 易用性 • • 简单易用 完整支持
- 38.目录 Contents 1 热补丁的两大流派 2 Tinker V1.0—牛刀小试 3 Tinker V2.0—自创功法 4 Tinker V3.0—修炼内功 5 Tinker V4.0—内外兼修 6 微信的开源之路
- 39.微信的开源之路 开源化计划 push check synchttps://github.com/Tencent/tinkerprivate repo github deploy mars tinker 高可用 mmdb pr check
- 40.shwenzhang@tencent.com WeMobileDev公众号