八、細節
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
}
}
}
```

其實說白了,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 生命周期