Android tinker升级之路分析

前言

目前app线上的tinker版本为 1.9.14.19,在最近的几个版本技术需求中,我们希望对tinker尝试进行升级,并对内部封装的tinker的包装sdk进行升级。升级过程中的一些热修流程和记录如下。

热修耗时时长分析

测试中,所有测试热修基本均可生效,但是对补丁合成生效时间有要求。耗时具体体现在:

  • tinker初始化
  • 下载补丁包
  • recover dex耗时(合并新dex文件)
  • parallel optimize dex(oat耗时)
  • 保存补丁信息(更新patch.info文件)

测试结果发现除了parallel optimize dex这一步,其他步骤耗时对比几乎不变,且耗时时长集中在parallel optimize dex这一环节。

升级前后数据对比

start to parallel optimize dex的时间对比(oat耗时)

机型 耗时(ms) 线上包(版本:1.9.14.19) 耗时(ms) 升级包(版本:1.9.14.25.2)
pixel 6a(Android 13) 63333 93393
1802 93400
1858 93386
vivo x80(Android 13) 63360 93399
2849 93457
小米10(android 12) 63375 93435
63338 93368
华为mate40(android 12) 4487 37506
5007 34520
小米8(Android 9) 6205 6439
6148 6220
vivo x9plus(Android 7.1.2) 78312 (热修不生效) 78035 (热修不生效)
131601 (热修不生效) 79475 (热修不生效)
小米5s Plus(Android 6.0.1) 76613 87717
64617 62501

不同Android系统下tinker的oat流程总结

  • 华为荣耀系统tinker会通过registerDexModule方法注册dex,不会进行重试步骤(1.9.14.25.2版本重试10次,1.9.14.19版本重试3次);
  • android8.0 之下直接使用DexFile.loadDex加载补丁触发dex2oat;
  • android8 ~ android10,通过NewClassLoaderInjector.triggerDex2Oat进行dex2oat;
  • android10以后不再支持从应用进程调用dex2oat,仅接受系统生成的OAT文件(TinkerDexOptimizer.triggerPMDexOptOnDemand方法);
  • 重试的逻辑发生在TinkerDexOptimizer.triggerPMDexOptOnDemand方法中,DexFile.loadDex和进程内通过NewClassLoaderInjector.triggerDex2Oat进行dex2oat不会走该逻辑;该重试的逻辑会增加30s耗时。
  • 在老旧手机上步骤二recover dex耗时明显比新设备耗时长,这个和机型性能有关,升级的差异不在步骤二。

相关逻辑请参考版本tinker源码TinkerDexOptimizer.OptimizeWorker类的run方法。

附:patch合成生效时间分析

目前热修是肯定需要重启app的,但是在app拉取热修配置,下载patch包,然后重启app之前的这个时间节点上,tinker需要对patch包进行合成生效的操作,这部分会有耗时。

tinker核心代码:

TinkerPatchService 
         -  doApplyPatch(this, intent);

tinker issue上已经有人反馈了:

补丁从安装到提示安装成功需要多久,我就改了个Toast打印的字符串,需要大概100s,这正常吗?项目比较大 · Issue #1316 · Tencent/tinker · GitHub

最新版本补丁合成很慢(50s),不管 dex2oat 是否成功都会循环 N 次 · Issue #1670 · Tencent/tinker · GitHub

这个问题tinker *v1.9.14.25* 已经做了优化:

**1、**base包更新或有新 patch 合成成功后删除老 patch 的逻辑改为异步实现以降低启动耗时。

**2、**dexopt 触发重试次数缩减到 10 次,避免部分机型 apply patch 耗时太长。

但是从tinker目前的反馈来看,最新的几个版本会出现合成时间变长的case,目前还处于open状态。为了验证升级之后的tinker,在合成生效时间上与之前版本的差异,进行了线上tinker版本(1.9.14.19)的对照测试。测试见下。

附:tinker版本升级内容记录

*v1.9.14.20*

  1. 修复了 OPPO & VIVO 部分机型加载 Tinker 时偶现的闪退问题。
  2. 增加了 Patch Dex 的 Dex2Oat 重试次数,以降低解释模式加载 Patch Dex 的概率。

*v1.9.14.21*

  1. 尝试修复极少数情况下因为 resources.apk 被意外修改导致 patch 后的资源找不到或失效的问题。

*v1.9.14.22*

  1. 修复了偶现的 Tinker ID 注入失败导致 Patch 包编译失败的问题。

*v1.9.14.23*

  1. 优化了判断 resources.apk 被意外修改导致资源 patch 失效的检测逻辑。
  2. 修复了连续两次 patch 中间更新了 base 包时可能导致最后一次 patch 失效的问题。
  3. 在 Patch 加载不成功时 installNativeLibraryABIWithoutTinkerInstalled() 方法不再注入 patch so 路径,避免 dex 和 so 不一致的问题。

*v1.9.14.23.1*

  1. 修复了 Android 4.4 设备上 getCurrentInstructionSet() 失败的问题

*v1.9.14.24*

  1. 修复了 R8 生成的特殊 DebugInfo 导致编译失败的问题。
  2. 增加 performSecondaryDexOpt 的重试次数,在重试失败后再尝试 registerDexModule,以尽量减小 Android R 上 odex 没有生成导致的性能开销。
  3. 在 performSecondaryDexOpt 重试无效前不在 OPPO、VIVO、XIAOMI、REDMI 的 Android S 或更新的系统上调 registerDexModule,规避已知的性能问题。
  4. 更新 *getProcessName* 的实现,在 *Android P* 及更新的系统上优先尝试 *Application.getProcessName()* 方法。

*v1.9.14.25*

  1. 增加了32位 Android N 及更旧的系统上使用解释模式触发 dexopt 的开关以帮助减少 32位上 VmSize 的开销。
  2. 修复部分机型上资源有变更时 patch 失败的问题。
  3. base包更新或有新 patch 合成成功后删除老 patch 的逻辑改为异步实现以降低启动耗时。
  4. dexopt 触发重试次数缩减到 10 次,避免部分机型 apply patch 耗时太长。

*v1.9.14.25.1*

  1. 修复了 anim 资源新增、修改检测逻辑,在 anim 资源发生新增或修改时会中断编译。
  2. 获取当前进程名的方法在 api level >= 18 的机器上优先使用反射 ActivityThread 的方式实现,若失败则改用 BufferedReader 读 proc 的方式实现。

*v1.9.14.25.2*

  1. 修复了部分机型上无法加载新增资源及修改资源不生效的问题(flutter加载asset时必现)。
  2. 新增了异步触发patched dex的dex2oat并且不等待其执行完毕的patch合成接口,以满足开启时长较短的App紧急修复问题时需要Patch能快速生效的需求。

参考

Android 热修复Tinker源码分析(二)补丁包的合成 - 掘金

相关推荐
HerayChen1 分钟前
HbuildderX运行到手机或模拟器的Android App基座识别不到设备 mac
android·macos·智能手机
顾北川_野2 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
hairenjing11234 分钟前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
小黄人软件29 分钟前
android浏览器源码 可输入地址或关键词搜索 android studio 2024 可开发可改地址
android·ide·android studio
dj15402252031 小时前
group_concat配置影响程序出bug
android·bug
周全全1 小时前
MySQL报错解决:The user specified as a definer (‘root‘@‘%‘) does not exist
android·数据库·mysql
- 羊羊不超越 -2 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
wk灬丨3 小时前
Android Kotlin Flow 冷流 热流
android·kotlin·flow
千雅爸爸3 小时前
Android MVVM demo(使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成)
android