APK 更新与安装
Android 系统从已安装 APK 读取 Manifest 和部分打包信息。Manifest 与配套资源表需要写回 APK;关闭 SO hot update 时,native lib 也走这条路径。Jugg 增量编译得到对应变化后,会修改最近一次可信的 Gradle APK、重新签名并安装,让系统读取更新后的安装包。开启 SO hot update 时,native lib 进入 overlay,重启 App 后加载。
这仍然属于增量部署:Jugg 复用已有 APK,只替换已经生成的局部文件,不重新执行完整 Gradle 构建。安装完成后,同一轮还可以继续应用 class、资源和 assets overlay。
哪些产物需要进入 APK
| 本轮产物 | 为什么需要更新 APK | 后续结果 |
|---|---|---|
AndroidManifest.xml patch | 系统从安装包读取组件、权限和其它 Manifest 信息 | 写回目标 APK,重新签名并安装 |
与 Manifest 配套的 resources.arsc | Manifest 中的资源引用必须和资源表保持一致 | 与 Manifest 一起更新 APK |
| 已经生成的 native lib,且关闭 SO hot update | App 从更新后的 APK 加载 .so | 写回对应 APK 后重新安装 |
普通 class、res/**、assets/** | 可以由增量 overlay 承载 | 安装后继续通过 Apply Changes 或 Hot Fix 下发 |
Jugg 只能写入已经由当前增量流程生成的文件。C/C++ 源码变化会先执行当前变体的 native task;ABI、packaging 配置变化或完整 Manifest merge 超出当前增量结果时,仍需 Gradle 重新生成 APK。
更新 APK 需要重新签名
Android 不接受内容被修改但签名未更新的 APK。Jugg 写入目标文件后,会使用当前工程的签名配置重新签名;签名配置缺失或无效时,APK 更新会明确失败,并把 Gradle 回退资格交给 Run 层。
签名身份必须与设备上已有的包一致,否则更新会被拒绝。Gradle SigningConfig 无法表达平台证书、厂商密钥或服务器签名流程时,可以在 Run Configuration 启用自定义 APK 签名脚本:Jugg 把对齐后的临时 APK 绝对路径作为最后一个参数交给项目脚本,脚本原地签名后,Jugg 仍用 apksigner verify 校验,通过才替换原 APK。启用脚本后本地签名配置不再是 APK 更新的前置条件,脚本失败也不会回退到本地 keystore 签名。完整契约见 自定义 APK 签名脚本。
多 APK 工程会根据产物的真实归属修改对应的 base、split 或 test APK。一个产物只写入它所属的 APK,不会为了方便全部塞进 base APK。
安装会建立新的设备基线
更新后的 APK 已经不再等同于设备上的旧安装。本轮不能继续假设旧 deployment cache 和 overlay ID 仍然有效,因此部署流程会进入状态恢复并安装更新后的 APK。
生成 Manifest 增量产物,或在关闭 SO hot update 时生成 native lib 产物
-> 写入最近的 Gradle APK
-> 使用工程签名重新签名,启用自定义签名脚本时改由项目脚本签名
-> 安装更新后的 APK
-> 重建 deployment cache 与设备 checkpoint
-> 重新生成待下发的 class 和 overlay
-> 完成本轮剩余增量部署安装替换了旧进程和旧 overlay 基线。Jugg 会清理已经不能继续复用的部署文件状态,再根据本轮编译结果重新组织剩余数据。这样 Manifest 或关闭 SO hot update 时的 native lib 与普通 class、资源可以在一次 Run 中共同生效。
如果当前 Run Configuration 启用了自定义 APK 安装脚本,普通 App 的“安装更新后的 APK”步骤会由项目脚本完成。Jugg 仍要求脚本安装本轮提供的 APK,并在 checksum 校验通过后重建 deployment cache;androidTest APK 不使用该脚本。
APK 更新和 Gradle 回退的区别
两条路径都会安装 APK,但重新生成 APK 的范围不同。
| 路径 | 复用内容 | 适用场景 |
|---|---|---|
| Jugg APK 更新 | 最近一次可信 Gradle APK,以及本轮已经生成的局部文件 | Manifest patch,以及关闭 SO hot update 时已有 native lib 等可确定性写回的变化 |
| Gradle 构建后安装 | 重新执行构建、打包和签名流程 | 构建脚本、依赖、C/C++ 编译、ABI 或 packaging 结果需要刷新 |
Recover 触发的重新安装也不等于 Gradle 回退。它通常安装当前已有 APK,用于修复设备状态;只有构建基线本身不可信时,才需要回到 Gradle。