八、细节
1、打包步骤
1)debug 打包
1.调用assembleDebug 编译得到一个debug 签名的apk(old apk),这是基础apk。
2.修改代码、更新res 文件、so 等。
3.将old apk 按gradle 中的参数规则,重命名为指定名字,还是放在bakApk目录下(该目录可更改)。
4.调用tinkerPatchDebug 生成补丁包于/build/outputs/tinkerPatch/目录(默认是patch_signed_7zip.apk)。
5.将补丁包复制到SD 卡目录下(目录可更改),在程序中调用打补丁方法,重启app 即可实现热修复。
2)release 打包步骤
1.调用assembleRelease 编译得到一个release 签名的apk(old apk),这是基础apk,还有一个mapping 文件。
2.修改代码、更新res 文件、so 等。
3.将old apk 与mapping 文件按gradle 中的参数规则,分别重命名为指定名字,还是放在bakApk 目录下(该目录可更改)。
4.调用tinkerPatchRelease 生成补丁包于/build/outputs/tinkerPatch/目录(默认是patch_signed_7zip.apk)。
5.将补丁包复制到SD 卡目录下(目录可更改),在程序中调用打补丁方法,重启app 即可实现热修复。
因为调用tinker 的release 打包需要用到签名文件的信息,所以还必须在app的build.gradle 中配置好签名文件。
```
android {
...
signingConfigs {
release {
try {
storeFile file("./keystore/release.keystore")
storePassword "testres"
keyAlias "testres"
keyPassword "testres"
} catch (ex) {
throw new InvalidUserDataException(ex.toString())
}
}
debug {
storeFile file("./keystore/debug.keystore")
}
}
...
buildTypes {
release {
minifyEnabled true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'),
project.file('proguard-rules.pro')
}
debug {
debuggable true
minifyEnabled false
signingConfig signingConfigs.debug
}
}
}
```
![](https://img.kancloud.cn/32/6e/326e50a53c624a83027b3495ce17463e_1013x486.jpg)
其实说白了,debug 与release 打包的差别,除了执行的命令不一样之外,release 打包比debug 打包多用到2 个文件(mapping.txt、R.txt)。
2、使用tinker 的注意事项与发现
1.tinker 编译时需要禁用instant run。
2.tinker 需要MultiDex。
3.上架前用assembleRelease 编译得到的apk、mapping.txt、R.txt 这3 个文
件要备份好,制作补丁时会用到。
4.多个补丁包的版本一样时,不影响打补丁(如:第一次补丁版本是1.0,第二
次补丁还是1.0 版本,是可以成功打上第二次补丁的)。
5.成功打上补丁后,补丁原文件会被删除,故项目中不必担心补丁原文件清理的
问题。
3、可能会遇到的错误
1)onLoadPatchListenerReceiveFail code 为-2
报错原文如下:
```
receive a patch file: /storage/emulated/0/patch_signed_7zip.apk, file size:3604
patch loadReporter onLoadPatchListenerReceiveFail: patch receive fail:
/storage/emulated/0/patch_signed_7zip.apk, code: -2
```
出现这种情况,请按如下两步进行排查:
1.查看文件路径是否正常。
2.查看清单文件中是否有添加SD 卡访问权限。
2)onLoadPatchListenerReceiveFail code 为-24
报错原文如下:
```
receive a patch file: /storage/emulated/0/patch_signed_7zip.apk, file size:3665
get platform:null
patch loadReporter onLoadPatchListenerReceiveFail: patch receive fail:
/storage/emulated/0/patch_signed_7zip.apk, code: -24
```
提示很明显,Tinker 获取不到platform 的值,请检查在app 的build.gradle文件中是否有如下配置,这部分配置了Tinker 补丁包支持的平台与版本号:
```
packageConfig {
configField("platform", "all")
configField("patchVersion", "1.0")
}
```
- 第一章 热修复设计
- 第一节、AOT/JIT & dexopt 与dex2oat
- 一、AOT/JIT
- 二、dexopt 与dex2oat
- 第二节、热修复设计之CLASS_ISPREVERIFIED 问题
- 一、前言
- 二、建立测试Demo
- 三、制作补丁
- 四、加载补丁
- 五、CLASS_ISPREVERIFIED
- 第三节、热修复设计之热修复原理
- 一、Android 热修复
- 二、Android 虚拟机和编译加载顺序
- 三、混合模式的理解
- 四、源码类到机器执行的文件过程
- 五、补丁包
- 六、类补丁生效原理
- 七、Davlik 虚拟机的限制
- 八、Davlik Class resolved by unexpected DEX: 限制和处理方式
- 九、类加载器的双亲委派加载机制
- 第四节、Tinker 的集成与使用(自动补丁包生成)
- 一、简述
- 二、Tinker 组件依赖
- 三、Tinker 的配置及任务
- 四、Tinker 封装与拓展
- 五、编写Application 的代理类
- 六、常用API
- 七、测试
- 八、细节
- 第二章 插件化设计
- 第一节、Class 文件与Dex 文件的结构解读
- 一、Class 文件
- 二、Dex 文件
- 三、Class 文件和Dex 文件对比
- 第二节、Android 资源加载机制详解
- 第三节、四大组件调用原理
- 第四节、so 文件加载机制
- 第五节、Android 系统服务实现原理
- 第三章 组件化框架设计
- 第一节、阿里巴巴开源路由框——ARouter 原理分析
- 第二节、APT 编译时期自动生成代码&动态类加载
- 第三节、Java SPI 机制
- 第四节、AOP&IOC
- 第五节、手写组件化架构
- 第四章 图片加载框架
- 第一节 图片加载框架选型
- 第二节 Glide 原理分析
- 第三节 手写图片加载框架实战
- 第五章 网络访问框架设计
- 第一节 网络通信必备基础
- 第二节 OkHttp 源码解读
- 第三节 Retrofit2 源码解析
- 第六章 RXJava响应式编程框架设计
- 第一节 RXJava之链式调用
- 第二节 RXJava之扩展的观察者模式
- 第三节 RXJava之事件变换设计
- 第四节 Scheduler 线程控制
- 第七章 IOC架构设计
- 第一节 依赖注入与控制反转
- 第二节 ButterKnife 原理上篇、中篇、下篇
- 第三节 IOC架构设计之Dagger2架构设计
- 第八章 Android架构组件 JetPack
- 第一节 LiveData的工作原理
- 第二节 Navigation 如何解决tabLayout 问题
- 第三节 ViewModel 如何感知View 生命周期及内核原理
- 第四节 Room 架构方式方法
- 第五节 dataBinding 为什么能够支持MVVM
- 第六节 WorkManager 内核揭秘
- 第七节 Lifecycles 生命周期