欢迎光临
我们一直在努力

Android Tinker 热修复集成与使用指南 1.9.15.2

Tinker 热修复集成与使用指南

版本:Tinker 1.9.15.2、AGP 8.2.2、Gradle 8.7。 目标:讲清环境、引入、集成、日常怎么用,并列出本项目踩过的坑。 项目仓库地址:点击进入 aar修复,请参照项目文件 docs目录下的 old和new .aar文件,关于项目如何打包 .aar,我会出一个新的文档


一、Tinker 能做什么

类型说明本项目
Dex 改 Java/Kotlin 业务逻辑 ✅ 已验证
资源 改 strings、colors、layout 等 ✅ 已验证
so 替换 APK 内 lib/<abi>/*.so ✅ 已配置(需自带 native)
本地 AAR 替换 libs/*.aar 后打补丁 ✅ 已验证(zcclib-release.aar)
Manifest 新组件 热增 Activity/Service 等 ❌ 未开启

说明: 手机上不会单独替换 .aar 文件,而是把新版 AAR 编译进新 APK,再与基准 APK 做差量生成补丁;用户加载补丁后,AAR 内的 Dex/资源/so 变更会随补丁生效。

不能做的: 不能改 SampleApplication 壳类;不能靠补丁在 Manifest 里注册新的 Activity/Service 等组件。


二、环境搭建

2.1 必备环境

  • JDK 11+(本项目 sourceCompatibility = 11)
  • Android SDK,compileSdk 34
  • Gradle Wrapper 8.7(不要用 Gradle 9,Tinker 插件会报 GFileUtils 等错误)

2.2 版本对照(与本项目一致)

组件版本
Gradle 8.7
Android Gradle Plugin 8.2.2
Tinker SDK + 插件 1.9.15.2

2.3 仓库

settings.gradle 中已配置 google()、mavenCentral(),并保留 Tinker / 阿里云镜像(拉 SevenZip 等依赖时有用)。


三、引入 Tinker

3.1 根工程 build.gradle

buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.2.2'
classpath 'com.tencent.tinker:tinker-patch-gradle-plugin:1.9.15.2'
}
}

3.2 模块 app/build.gradle

apply plugin: 'com.android.application'
apply plugin: 'com.tencent.tinker.patch' // 必须在 application 插件之后

dependencies {
implementation 'com.tencent.tinker:tinker-android-lib:1.9.15.2'
implementation 'androidx.multidex:multidex:2.0.1'
}

3.3 Release 构建注意

  • multiDexEnabled true
  • minifyEnabled true 时必须有 mapping.txt
  • shrinkResources 必须为 false(Tinker 要求)
  • 配置 Release 签名(基准包与补丁包签名一致)

四、集成步骤(对照本项目)

4.1 核心类分工

SampleApplication ← 壳,不能热修,只做 Tinker 入口
SampleApplicationLike ← 真正 Application 逻辑,可热修
TinkerManager ← install / loadPatch / cleanPatch
PatchResultService ← 合成成功后冷重启
TinkerPatchService ← :patch 进程合成补丁

4.2 Application 壳

AndroidManifest.xml 中 android:name 指向 SampleApplication,不要直接写 ApplicationLike。

SampleApplication 继承 TinkerApplication,并指定代理类:

public SampleApplication() {
super(
ShareConstants.TINKER_ENABLE_ALL, // dex + so + res
"com.example.tinkerdemo.app.SampleApplicationLike",
"com.tencent.tinker.loader.TinkerLoader",
false // 正式环境建议 true:校验补丁 MD5
);
}

4.3 在 attachBaseContext 安装 Tinker

SampleApplicationLike.onBaseContextAttached() 中:

  • MultiDex.install(base)
  • TinkerManager.installTinker(this)
  • 必须在 attachBaseContext 阶段完成,不能拖到 onCreate。

    4.4 AndroidManifest 必配项

    • meta-data TINKER_ID:与 build.gradle 里 manifestPlaceholders 一致
    • Service(本项目已注册):
      • TinkerPatchService(:patch 进程)
      • PatchResultService(主进程,合成后杀进程冷启动)
      • TinkerPatchForeService(Android 8+ 前台保活)

    4.5 权限(本地调试补丁路径)

    • READ/WRITE_EXTERNAL_STORAGE
    • Android 11+:MANAGE_EXTERNAL_STORAGE(读 /sdcard/patch_signed_7zip.apk)
    • android:requestLegacyExternalStorage="true"(调试方便)

    4.6 混淆 proguard-rules.pro

    至少保留:

    • com.tencent.tinker.**
    • SampleApplication(loader 白名单)
    • ApplicationLike、Patch/Load Reporter
    • R$* 成员(资源 ID 稳定)

    打补丁时使用基准包的 mapping.txt(applyMapping)。

    4.7 tinkerPatch 配置要点

    def TINKER_ID = "base-1.0.0"
    def OLD_APK = "${rootDir}/patch/base/app-release.apk"
    def OLD_MAPPING = "${rootDir}/patch/base/mapping.txt"
    def OLD_RESOURCE = "${rootDir}/patch/base/R.txt"

    android {
    defaultConfig {
    manifestPlaceholders = [TINKER_ID: TINKER_ID]
    }
    }

    tinkerPatch {
    oldApk = OLD_APK
    ignoreWarning = true // 含 Java/AAR 改动时建议 true,见「常见问题」
    useSign = true

    buildConfig {
    applyMapping = OLD_MAPPING
    applyResourceMapping = OLD_RESOURCE
    tinkerId = TINKER_ID
    }

    dex {
    dexMode = "jar"
    pattern = ["classes*.dex"]
    loader = [
    "com.tencent.tinker.loader.*",
    "com.example.tinkerdemo.app.SampleApplication"
    ]
    }
    lib { pattern = ["lib/*/**.so"] }
    res { pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"] }
    }

    4.8 本地 AAR 与热修复(已验证)

    implementation files('libs/zcclib-release.aar')

    两种场景不要搞混:

    场景操作
    首次接入 AAR(发版) 把 AAR 放进 app/libs/,打基准包 → 更新 patch/base/ → 安装到手机
    仅热修 AAR(已上线) 不要动基准包;用改好的 .aar 覆盖 app/libs/ 里同名文件 → tinkerPatchRelease → 推补丁

    AAR 热修步骤(本项目已验证):

  • 手机上已是含旧版 AAR 的基准包(patch/base/app-release.apk 与之一致)。
  • 在外部改好 SDK,重新打包得到新的 zcclib-release.aar(或你的 aar 文件名)。
  • 将新 AAR 替换到 app/libs/zcclib-release.aar(路径、依赖方式不变)。
  • 执行 .\\gradlew.bat clean(可选,建议 clean 后打补丁)→ .\\gradlew.bat tinkerPatchRelease。
  • 推送 app/build/tmp/tinkerPatch/patch_signed_7zip.apk,App 内加载补丁并冷启动。
  • 补丁日志中通常能看到 Dex 差量(AAR 内 Java 变更)以及 资源差量(若 AAR 含 layout、strings 等)。若 AAR 带 jni/*.so,还会走 lib 差量。

    注意: 热修 AAR 时仍需使用基准包的 mapping.txt、R.txt;若新版 AAR 导致资源 ID 体系变化过大,需评估是否应发新基准包而非打补丁。


    五、目录与基准包

    TinkerClaude/
    ├── patch/
    │ ├── base/ # 基准包(“已上线版本”)
    │ │ ├── app-release.apk
    │ │ ├── mapping.txt
    │ │ └── R.txt
    │ └── patch_signed_7zip.apk # 可选:备份最近一次补丁
    ├── app/build/tmp/tinkerPatch/ # 补丁真正输出目录(推这个)
    │ ├── patch_signed_7zip.apk
    │ └── patch_signed.apk
    └── keystore/tinker_demo.jks # Release 签名

    每次发布新基准包都要更新 patch/base/ 三件套,并 adb install -r 装到手机。


    六、使用流程(推荐顺序)

    6.1 发布基准包(模拟上线)

    # Windows
    .\\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

    安装到手机:

    adb install -r patch/base/app-release.apk

    6.2 修改代码 / 资源 / AAR 后打补丁

    在不改变 patch/base/ 基准包的前提下,任选其一或组合修改:

    • 改 App 内 Java、layout、strings 等
    • 用新版 .aar 覆盖 app/libs/ 下同名文件(AAR 热修,已验证)

    然后:

    .\\gradlew.bat tinkerPatchRelease

    仅替换 AAR 时:基准包仍是旧 AAR 打进 APK 的那一版;新 AAR 只参与「新 APK」构建,用于和基准做 diff,无需为此重新安装基准包(除非你还改了 Manifest、TINKER_ID 等)。

    补丁输出位置(重要):

    • ✅ 使用:app/build/tmp/tinkerPatch/patch_signed_7zip.apk
    • ❌ 不要只推:app/build/outputs/apk/tinkerPatch/release/(可能是旧文件)

    6.3 推送到真机并加载

    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 # 校验大小

    App 内:从外部存储加载补丁 → 授权「所有文件访问权限」→ 合成成功后会 自动冷重启(PatchResultService)。

    6.4 验证是否生效

    • 看 资源演示页 文案/颜色是否变化
    • logcat 过滤 Tinker.TinkerLoader,应出现 tryLoadPatchFiles: load end, ok!
    • 首次装基准包未打补丁时,code=-2(无 tinker 目录)是正常现象

    6.5 清除补丁

    主界面 清除补丁 → 强制停止 App → 再打开,即回到基准包行为。


    七、代码里如何触发补丁

    7.1 从 SD 卡加载(Demo 默认)

    路径:/storage/emulated/0/patch_signed_7zip.apk(见 PatchFileUtils)

    TinkerManager.loadPatch(context, patchPath);

    7.2 从 assets 加载(本地演示)

    将补丁放入 app/src/main/assets/patch_signed_7zip.apk,点击「从 assets 加载」。

    7.3 生产环境建议

    用 OkHttp / 下载 SDK 把补丁下到私有目录或 getExternalFilesDir,再调用:

    TinkerInstaller.onReceiveUpgradePatch(context, absolutePath);

    合成成功后务必 冷启动(杀进程或依赖 PatchResultService)。


    八、能力边界速查

    场景是否支持
    改 Activity / 工具类 Java 代码 ✅ Dex
    改/新增 layout、strings(保持 R.txt 稳定) ✅ 资源
    覆盖 app/libs/xxx.aar 后打补丁 ✅ 已验证(Dex/资源/so 差量)
    手机上单独拷贝一个 .aar 文件即生效 ❌(须打补丁包并加载)
    AAR 仅含 Java,无 so ✅ Dex 补丁即可
    AAR 含 layout/资源 ✅ 资源补丁(需 applyResourceMapping)
    AAR 含 jni/*.so ✅ so 补丁(ABI 与基准一致)
    新增 Manifest Activity 并启动
    改 SampleApplication
    改 AndroidManifest 里 Service 注册 ❌ 需重装基准包

    九、常见问题

    9.1 打补丁失败:ShareTinkerInternals loader 类变更

    现象: some loader class has been changed in new primary dex

    处理: tinkerPatch { ignoreWarning = true }(本项目已开启)。这是 R8 重编译后的无害差异,不影响业务类热修。

    9.2 补丁推了但界面不变

  • 确认推的是 build/tmp/tinkerPatch/ 下最新文件
  • 用 adb shell stat -c %s 核对大小,不要只看 ls -l 时间
  • 必须 冷启动,不要只划掉后台
  • 手机上必须是 基准包,不是已包含新资源的完整 APK
  • 合成成功后 SD 卡补丁可能被删除,需重新 push
  • 9.3 patch_meta.info / code=-2 日志

    • 首次安装、未加载过补丁:正常
    • 重装基准包后:先 清除补丁 再加载新补丁

    9.4 mkdir res_temp/res 报错但显示合成成功

    部分机型(如 vivo)常见,若 onPatchResult: success=true 且冷启动后界面已更新,可忽略。

    9.5 Gradle 9 构建失败

    请使用 Gradle 8.7,不要用 9.x milestone。

    9.6 改了 AndroidManifest(新增 Service 等)

    Manifest 变更 不能 靠补丁生效,需 重新打基准包并安装。

    9.7 何时必须更新基准包

    • 新功能首次上线(新的基准 APK)
    • 修改了 Manifest 组件
    • 修改了 TINKER_ID
    • 换了签名或 ABI 策略

    仅改业务代码 / 资源 / 覆盖 libs 下 AAR 后打补丁:只打补丁,不更新基准。

    9.8 AAR 热修后无效果

  • 确认手机安装的是旧版 AAR 的基准包,而不是已手动集成新 AAR 编出来的完整 APK。
  • 确认 app/libs/ 里已是新版 aar,且执行过 tinkerPatchRelease(建议先 clean)。
  • 补丁需从 build/tmp/tinkerPatch/ 推送,加载后 冷启动。
  • 查看构建日志是否有 Gen classes.dex patch(有 Java 变更时应有 Dex 差量)。

  • 十、命令速查

    目的命令
    打基准包 .\\gradlew.bat :app:assembleRelease
    打补丁 .\\gradlew.bat tinkerPatchRelease
    安装基准 adb install -r patch/base/app-release.apk
    推送补丁 adb push app/build/tmp/tinkerPatch/patch_signed_7zip.apk /sdcard/patch_signed_7zip.apk
    解决 R8 锁文件 .\\gradlew.bat –stop 后 clean 再编

    十一、本项目关键文件索引

    文件作用
    app/build.gradle Tinker 插件、tinkerPatch、TINKER_ID
    app/src/main/AndroidManifest.xml 权限、Service、TINKER_ID
    app/…/SampleApplication.java Tinker 壳
    app/…/SampleApplicationLike.java MultiDex + installTinker
    app/…/TinkerManager.java 安装与加载补丁
    app/…/PatchResultService.java 合成成功冷重启
    app/…/MainActivity.java 加载/清除补丁、权限
    app/…/PatchFileUtils.java 补丁路径
    app/proguard-rules.pro 混淆保留规则
    patch/base/ 基准 APK + mapping + R.txt

    十二、参考链接

    • Tencent Tinker 官方仓库
    • 本 Demo 包名:com.example.tinkerdemo
    • 更多项目使用和详细 参见 Android Tinker Demo 使用手册
    赞(0)
    未经允许不得转载:171主机测评 » Android Tinker 热修复集成与使用指南 1.9.15.2
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址