Skip to content

Direct Overlay ​

Direct Overlay 是 Jugg 在设备尚未进入在线 Apply Changes ready 状态时使用的 overlay 写入旁路。它直接把增量 overlay 写入 App sandbox,再由外层部署流程负责启动、重启或测试收口。

Direct Overlay 适用条件 ​

操作场景当前支持情况部署策略
设备未 ready,但历史和 cache 匹配支持直接写入 App sandbox 中的 overlay
Android O 及以上、Apply Changes 前提成立支持使用 run-as 写入 App sandbox
run-as 无成功标记、UID 越界或 SELinux label 不一致的 class、资源或 assets 变更权限探测成功时支持固定使用普通 shell、root adbd 或设备支持的非交互 su 命令形式写入真实 data 目录
run-as、普通 shell、root adbd 和非交互 su 全部不可用兼容 payload 支持,普通 payload 先转兼容部署把兼容 payload 暂存到 App 专属 external files 目录,由 App 在下次启动时导入,不推送任何 JVMTI agent
需要提前准备 Apply Changes startup agent支持由 Direct Overlay 路径推送 AS startup agent
overlay id 与预期不匹配不强行写入转 recover 或 reinstall
writer 已修改 overlay 后失败不回退旧 Apply Changes阻止在半提交状态继续部署

IMPORTANT

Direct Overlay 只替换 overlay update transport,不接管完整部署生命周期。启动 App、重启 App、运行 androidTest 和提交历史仍由外层部署流程负责。

这项能力如何生效 ​

text
设备不 ready 且允许 Direct Overlay
  -> 读取 deployment cache 和预期 overlay id
  -> 检查设备端 overlay id
  -> 构造 overlay zip payload
  -> 通过 ADB 传输到设备
  -> 以目标 App 身份原子更新 sandbox 中的 overlay
  -> 最后写入新 overlay id
  -> 更新 deployment cache

Recover 阶段会检查 history、cache 和设备端 overlay 状态;真正写入前至少会使用 cache 校验设备端 overlay ID。写入过程中,新 overlay ID 最后提交;如果在修改 overlay 目录后失败,会把状态视为 dirty,不再尝试旧 Apply Changes 伪回退。

当 run-as、UID 或 SELinux label 不满足 Android Studio Deployer 前提时,同一轮部署会复用一个已经选定权限模式的 sandbox executor,确保 overlay、startup agent 和 JVMTI Hot Reload 不会在 root 状态变化后切换路径。

Direct 权限模式会分别修复数据文件与 Agent .so 的 SELinux label:overlay 数据继承 App 缓存目录的动态 categories,.so 使用 App 进程可执行的类型。修复工具打印附加信息时,不会改变写入命令的成功判断。

使用边界 ​

Direct Overlay 需要同时满足这些条件:

  • 用户或调用方允许 Direct Overlay。
  • 设备不是普通 ready deploy 状态。
  • deployment cache 存在且 overlay checkpoint 可校验。
  • deploy data 非空,且不是 install。
  • 设备系统版本满足要求,App sandbox 可通过本轮选定的 run-as、普通 shell、root adbd 或非交互 su 模式写入。

run-as、UID 或 SELinux label 不兼容时,Jugg 可以直接下发 class、资源和 assets。纯方法体变化可在线替换;Android 11+ 的资源、assets 或与代码混合的变化会刷新当前进程资源并重建 Activity,刷新失败时再重启 App。Android 8~10 和兼容部署沿用需要重启进程的资源路径。Manifest 仍走 APK 更新与安装;native library 在开启 SO hot update 时进入 overlay 并重启 App,关闭时走 APK 更新。缺少 deployment cache 时会直接报告失败。

普通 shell、root adbd 和非交互 su 也全部不可用时,Jugg 不再尝试写入 App sandbox:普通的 class、资源和 assets 变更先转成兼容部署,再把兼容 payload 暂存到 shell 可写、App 可读的 /sdcard/Android/data/<package>/files/jugg/rootless-compat/<requestId>/,只重启 App 一次,由 App 通过 Context.getExternalFilesDir(null) 在启动早期导入 code_cache/.overlay。这条路径不推送、复制或 attach 任何 JVMTI agent,App 确认导入成功前不会推进 deployment cache、部署历史和文件状态;导入失败或超时会保留旧 overlay 并明确失败。

相关页面 ​