Android Tinker Demo 使用手册
本文专门说明 本 Demo 里怎么改代码、怎么验证热修复 ,侧重操作步骤与文件对照。
项目地址:点击进入
承接上一篇文章 - 环境与集成说明见:Tinker集成与使用指南.md
一、Demo 能测什么
| 场景 | 入口 / 页面 | 补丁类型 |
|---|---|---|
| 资源:strings / colors / dimens | 资源修复演示 页 | 资源 |
| 资源:drawable / raw / assets | 资源修复演示 页 | 资源 |
| 资源:layout 文案与结构 | 资源修复演示 页 + 主界面 | 资源 |
| Dex:主界面按钮逻辑 | 主界面 btn_add |
Dex |
| Dex:主界面 / 业务类 Java | 任意可热修类 | Dex |
AAR:zcclib-release.aar |
打开 aar 页面 | Dex + 资源(视 AAR 内容) |
| 加载补丁(SD 卡 / assets) | 主界面 | --- |
| 清除补丁 | 主界面 | --- |
统一规则: 手机上必须先装 基准包 (patch/base/app-release.apk),再加载补丁;生效需 冷启动(合成成功后会自动杀进程重启)。
二、先搞清:基准版 vs 补丁版
打补丁时,Tinker 对比的是两份 Release APK:
patch/base/app-release.apk ← 基准(模拟已上线,不要改 patch/base 里的内容来"试效果")
app/build/outputs/.../app-release.apk ← 新包(你改完代码后编出来的)
正确做法:
- 改代码前:基准包已打进
patch/base/并装到手机。 - 改代码后:只跑
tinkerPatchRelease,不要 再覆盖patch/base/(除非你要发新一版基准)。 - 推送补丁 → App 加载 → 冷启动 → 看界面。
资源 ID 稳定: 打补丁的新包构建时会用 patch/base/R.txt(applyResourceMapping)。改 values / layout 时尽量 只改内容 ,不要随意删资源名或大规模改 res 结构。
三、通用流程(每次验证都走这套)
3.1 发布基准包(仅首次或发新版时)
bash
.\gradlew.bat clean :app:assembleRelease
拷贝到 patch/base/:
| 源 | 目标 |
|---|---|
app/build/outputs/apk/release/app-release.apk |
patch/base/app-release.apk |
app/build/outputs/mapping/release/mapping.txt |
patch/base/mapping.txt |
app/build/intermediates/runtime_symbol_list/release/R.txt |
patch/base/R.txt |
bash
adb install -r patch/base/app-release.apk
3.2 改代码 → 打补丁 → 推送
bash
.\gradlew.bat tinkerPatchRelease
补丁文件(务必用这个):
app/build/tmp/tinkerPatch/patch_signed_7zip.apk
bash
adb push app/build/tmp/tinkerPatch/patch_signed_7zip.apk /sdcard/patch_signed_7zip.apk
adb shell stat -c %s /sdcard/patch_signed_7zip.apk
3.3 在 App 里加载
- 打开 Tinker 热修复 Demo
- 点 「从外部存储加载补丁」
- Android 11+:授予 所有文件访问权限,返回 App 会自动继续加载
- 看到「补丁加载请求已发送」→ 合成成功后会 自动冷重启 (
PatchResultService) - 再进对应页面看效果
可选:把补丁放进 app/src/main/assets/patch_signed_7zip.apk,用 「从 assets 加载补丁」(不经过 SD 卡)。
3.4 清除补丁(回到基准表现)
主界面 → 清除所有补丁 → 强制停止 App → 再打开。
四、资源热修复(重点)
验证页面:主界面 → 打开资源修复演示页 (ResourceDemoActivity)。
逻辑在 ResourceDemoActivity.java:通过 R.string / R.color / R.dimen / R.drawable / raw / assets 读资源,不要在 Java 里写死要热修的文字或颜色。
4.1 strings.xml(文字)
| 项目 | 说明 |
|---|---|
| 改哪个文件 | app/src/main/res/values/strings.xml |
| 演示用 key | demo_patchable_text |
| 页面上哪一块 | 资源演示页第一张卡片「values/strings.xml」 |
基准版示例(打基准包前用这个):
xml
<string name="demo_patchable_text">【基准版本】这是来自 strings.xml 的文字。热修复后,这里会显示新内容。</string>
补丁版示例(打补丁前改成):
xml
<string name="demo_patchable_text">【补丁版本】这段文字来自 strings.xml,已通过热修复更新。</string>
主界面也会用到的 strings(可一并改):
| key | 用途 |
|---|---|
btn_open_add |
「这是新增的补丁热修复按钮」按钮文案 |
btn_open_aar |
打开 AAR 页按钮 |
app_name |
标题 |
改完后:tinkerPatchRelease → 推补丁 → 加载 → 冷启动 → 进资源演示页看第一段文字。
4.2 colors.xml(颜色)
| 项目 | 说明 |
|---|---|
| 改哪个文件 | app/src/main/res/values/colors.xml |
| 演示用 key | demo_patchable_color |
| 代码怎么用 | ResourceDemoActivity 里 tv_demo_color.setTextColor(getResources().getColor(R.color.demo_patchable_color, null)) |
| 页面上哪一块 | 第二张卡片「values/colors.xml」------文字颜色会变 |
基准版:
xml
<color name="demo_patchable_color">#1976D2</color>
补丁版(例如粉红):
xml
<color name="demo_patchable_color">#E91E63</color>
说明:卡片里固定写着「这段文字的颜色来自 demo_patchable_color」,变的是 字体颜色,不是这段说明文字本身。
4.3 dimens.xml(字号)
| 项目 | 说明 |
|---|---|
| 改哪个文件 | app/src/main/res/values/dimens.xml |
| 演示用 key | demo_patchable_text_size |
| 页面上哪一块 | 第三张卡片「values/dimens.xml」 |
基准版:
xml
<dimen name="demo_patchable_text_size">16sp</dimen>
补丁版:
xml
<dimen name="demo_patchable_text_size">24sp</dimen>
tv_demo_dimen 会显示类似「当前字号:xx.x px(来自 dimens.xml)」。
4.4 drawable(矢量图 / 图片)
| 项目 | 说明 |
|---|---|
| 改哪个文件 | app/src/main/res/drawable/ic_demo_patch.xml |
| 演示用 key | R.drawable.ic_demo_patch |
| 页面上哪一块 | 第四张卡片「drawable」里的盾牌图标 |
改法示例: 修改 path 的 android:fillColor:
xml
<!-- 基准:蓝色 -->
<path android:fillColor="#1976D2" ... />
<!-- 补丁:绿色 -->
<path android:fillColor="#388E3C" ... />
若是 png/jpg ,替换 res/drawable/ 下同名文件即可(保持文件名不变)。
4.5 layout.xml(布局)
| 项目 | 说明 |
|---|---|
| 资源演示布局 | app/src/main/res/layout/activity_resource_demo.xml |
| 主界面布局 | app/src/main/res/layout/activity_main.xml |
推荐改法(安全): 只改已有控件上的 android:text、android:padding、android:visibility 等,不要在补丁里新增必须在 Manifest 注册的组件。
示例(资源演示页某卡片标题):
xml
<!-- 基准 -->
android:text="📝 values/strings.xml(可热修复)"
<!-- 补丁 -->
android:text="📝 strings 已热修复 ✅"
注意: ResourceDemoActivity 在 onCreate 里还会用代码设置 tv_demo_string 的文本(来自 R.string.demo_patchable_text)。若只改 layout 里别的静态文字,和 strings 演示互不冲突;strings 卡片正文以 strings.xml 为准。
4.6 raw(原始资源)
| 项目 | 说明 |
|---|---|
| 改哪个文件 | app/src/main/res/raw/demo_raw_text.txt |
| 代码 | openRawResource(R.raw.demo_raw_text) |
| 页面上哪一块 | 「raw」卡片 |
直接改 txt 内容,例如把「基准版本」改成「补丁版本」即可。
4.7 assets(资产目录)
| 项目 | 说明 |
|---|---|
| 改哪个文件 | app/src/main/assets/demo_assets_text.txt |
| 代码 | getAssets().open("demo_assets_text.txt") |
| 页面上哪一块 | 「assets」卡片 |
与 raw 类似,改文本内容后打补丁即可。
4.8 资源热修自检清单
| 检查项 | 说明 |
|---|---|
| 手机上是基准包 | 不是把「含新资源的完整 APK」当基准又打补丁 |
| 补丁路径正确 | /sdcard/patch_signed_7zip.apk,且 stat 大小与电脑一致 |
| 已冷启动 | 不要只划掉后台 |
| 构建日志 | 应有 Found modify resource / resources.arsc 相关输出 |
| 仍无效 | 先 清除补丁,再重新 push 并加载 |
五、Dex 热修复(Java 代码)
5.1 主界面「新增按钮」逻辑(btn_add)
| 项目 | 说明 |
|---|---|
| 布局 | activity_main.xml 里已有 btn_add(基准包安装时已存在) |
| 代码 | MainActivity.java → btn_add.setOnClickListener |
基准版示例:
java
Toast.makeText(MainActivity.this, "我是基准版按钮", Toast.LENGTH_SHORT).show();
补丁版示例:
java
Toast.makeText(MainActivity.this, "我是热修复新增的按钮", Toast.LENGTH_SHORT).show();
验证:主界面点击该按钮,看 Toast 文案是否变化。
说明: 按钮本身在基准 layout 里已有,热修的是 点击逻辑(Dex) ;按钮上的文字来自 strings.xml 的 btn_open_add,可同时做 资源补丁 改文案。
5.2 改其他 Java 类
可修改例如:
MainActivity.java(除SampleApplication外)ResourceDemoActivity.javaTinkerManager等工具类
打补丁前确认 app/build.gradle 中:
gradle
ignoreWarning = true // 含 Java / AAR 改动时建议开启
构建日志应出现:Gen classes.dex patch file。
5.3 不能热修的类
app/.../SampleApplication.java(Tinker 壳,在 loader 白名单)com.tencent.tinker.loader.*
业务代码请写在 SampleApplicationLike 及普通 Activity 中。
六、AAR 热修复(zcclib-release.aar)
| 项目 | 说明 |
|---|---|
| 依赖位置 | app/libs/zcclib-release.aar |
| Demo 入口 | 主界面 「打开 aar 页面」 → SecondActivity(AAR 内 Activity,Manifest 基准里已注册) |
6.1 首次接入 AAR(发基准)
- 将
zcclib-release.aar放入app/libs/ implementation files('libs/zcclib-release.aar')- 打基准包 → 更新
patch/base/→ 安装到手机
6.2 仅热修 AAR(已上线后)
- 手机已是 旧版 AAR 的基准包
- 用新版 aar 覆盖
app/libs/zcclib-release.aar(文件名不变) .\gradlew.bat clean(建议)→.\gradlew.bat tinkerPatchRelease- 推送补丁 → 加载 → 冷启动
- 点 打开 aar 页面 看 AAR 内界面/逻辑是否更新
补丁通常包含 Dex 差量 ;若 AAR 带 layout/strings,还会有 资源差量。
七、主界面其它操作
7.1 从外部存储加载补丁(推荐真机调试)
- 路径:
/storage/emulated/0/patch_signed_7zip.apk(见PatchFileUtils.getExternalPatchPath()) - 需要存储权限(见下节)
- 合成成功后可能 删除 SD 卡上的补丁文件 (
PatchResultService),再次测试需重新adb push
7.2 从 assets 加载补丁
- 将
patch_signed_7zip.apk放到app/src/main/assets/ - 重新安装 含该 assets 的 APK(或仅用于本地调试时装一次带 assets 的包)
- 点 从 assets 加载补丁
适合不依赖 SD 卡权限的本机测试。
7.3 查看 Tinker 状态
主界面顶部 状态卡片 显示:是否已安装 Tinker、是否已加载补丁、dex/res 是否启用、TINKER_ID 等。
7.4 打开资源修复演示页
跳转 ResourceDemoActivity,集中查看本章第四节所有资源项。
八、权限说明(外部补丁必读)
| 系统版本 | 要求 |
|---|---|
| Android 6--10 | 运行时 READ_EXTERNAL_STORAGE |
| Android 11+ | 所有文件访问权限 (MANAGE_EXTERNAL_STORAGE),跳转系统设置后返回 App 会自动继续加载 |
未授权时点击「从外部存储加载补丁」会提示:请授予「所有文件访问权限」后重试。
九、Demo 场景速查表
| 你想验证 | 改什么 | 在哪看效果 |
|---|---|---|
| 字符串 | values/strings.xml → demo_patchable_text |
资源演示页 → strings 卡片 |
| 颜色 | values/colors.xml → demo_patchable_color |
资源演示页 → colors 卡片 |
| 字号 | values/dimens.xml → demo_patchable_text_size |
资源演示页 → dimens 卡片 |
| 图标 | drawable/ic_demo_patch.xml |
资源演示页 → drawable 卡片 |
| 布局文案 | layout/activity_*.xml |
对应页面 |
| raw 文本 | res/raw/demo_raw_text.txt |
资源演示页 → raw 卡片 |
| assets 文本 | assets/demo_assets_text.txt |
资源演示页 → assets 卡片 |
| 按钮点击逻辑 | MainActivity → btn_add |
主界面 Toast |
| AAR 升级 | 覆盖 libs/zcclib-release.aar |
主界面 → 打开 aar 页面 |
| 回退 | 主界面 → 清除补丁 + 冷启动 | 恢复基准表现 |
十、推荐练习顺序(第一次跑通 Demo)
- 只做 strings:基准用「基准版本」文案 → 补丁改成「补丁版本」→ 资源演示页验证
- 只做 colors :
#1976D2→#E91E63 - strings + colors 一起:打一份补丁,一次加载
- Dex :改
btn_add的 Toast - AAR:覆盖 aar 后打补丁,进 SecondActivity 验证
每一步都走 第三节通用流程,避免跳过「装基准包」或「冷启动」。
十一、常见现象(Demo 专用)
| 现象 | 是否正常 | 处理 |
|---|---|---|
首次打开 code=-2 |
正常 | 尚未加载过补丁 |
patch_meta.info 找不到 |
正常 | 首次合成前无此文件 |
| 合成成功但 SD 卡补丁没了 | 正常 | 被 PatchResultService 删除,需重新 push |
mkdir res_temp/res 报错仍 success |
部分机型常见 | 冷启动后看界面是否已更新 |
| 资源没变 | --- | 确认推的是 tmp/tinkerPatch 下最新包、已冷启动、手机是基准包 |
| 打补丁失败 loader 类 | --- | ignoreWarning = true |
十二、相关文件索引
| 路径 | 作用 |
|---|---|
app/src/main/res/values/strings.xml |
可热修字符串 |
app/src/main/res/values/colors.xml |
可热修颜色 |
app/src/main/res/values/dimens.xml |
可热修尺寸 |
app/src/main/res/drawable/ic_demo_patch.xml |
可热修图标 |
app/src/main/res/layout/activity_resource_demo.xml |
资源演示布局 |
app/src/main/res/layout/activity_main.xml |
主界面布局 |
app/src/main/res/raw/demo_raw_text.txt |
raw 演示 |
app/src/main/assets/demo_assets_text.txt |
assets 演示 |
app/.../ResourceDemoActivity.java |
资源读取逻辑 |
app/.../MainActivity.java |
加载补丁 / Dex 演示 |
app/.../PatchFileUtils.java |
补丁路径 |
app/libs/zcclib-release.aar |
AAR 热修 |
patch/base/ |
基准三件套 |
文档对应 APP项目工程Demo 结构;若你本地 strings.xml 等已是补丁态文案,打新基准前请先改回「基准版」再执行 assembleRelease。