Android 熱修復 - Tinker 實現及踩過的坑

GoileoLee發表於2018-01-03

轉載請註明出處:https://juejin.im/post/5a44648a6fb9a045023bef4d

寫在開頭

Android 熱修復 - 各框架原理學習及對比 一文中,介紹了Nuwa、Robust、Andfix 和 Tinker 的實現原理,以及優缺點對比等。下面我們就讓 Tinker-Demo跑起來,看看實際效果以及解決整合過程中遇到的問題。

Tinker-Demo 效果

下載 Github 上的開原始碼,然後僅需匯入 tinker-sample-android 工程即可。

新增依賴

在專案的 build.gradle 中,新增 tinker-patch-gradle-plugin 的依賴

buildscript {
    dependencies {
        classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1')
    }
}
複製程式碼

然後在app的gradle檔案app/build.gradle,我們需要新增tinker的庫依賴以及apply tinker的gradle外掛.

dependencies {
	//可選,用於生成application類 
	provided('com.tencent.tinker:tinker-android-anno:1.9.1')
    //tinker的核心庫
    compile('com.tencent.tinker:tinker-android-lib:1.9.1') 
}
...
//apply tinker外掛
apply plugin: 'com.tencent.tinker.patch'
複製程式碼

準備好後,執行...

tinkerId is not set!!!

看一下app/build.gradle中在哪裡設定tinkerId。

tinkerId

def getTinkerIdValue() {
    return hasProperty("TINKER_ID") ? TINKER_ID : gitSha()
}
複製程式碼
def gitSha() {
        String gitRev = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()
        ...
複製程式碼

這裡是 Tinker 官方的常見問題文件 Tinker常見問題文件

tinkerId is not set 官網回答

這裡設定成版本號即可

String gitRev = '1.9.1'
複製程式碼

再執行... 點選 SHOW INFO 按鈕

這裡寫圖片描述

生成補丁包

MainActivity.java中新增程式碼

Toast.makeText(this, "hello, Tinker", Toast.LENGTH_SHORT).show();
複製程式碼

在app/build.gralde中,將剛才生成的apk包標記為oldApk

if (buildWithTinker()) {
    apply plugin: 'com.tencent.tinker.patch'
    tinkerPatch {
    ...
        oldApk = getOldApkPath()
複製程式碼
def getOldApkPath() {
    return hasProperty("OLD_APK") ? OLD_APK : ext.tinkerOldApkPath
}
複製程式碼

oldApkPath

包名改成和左邊的一樣。 在底部Terminal中輸入生成補丁包的命令 graldew tinkerPatchDebug ... 報錯

com.tencent.tinker.build.util.TinkerPatchException:
Warning: ignoreWarning is false, manifest was changed, while hot plug component support mode is disabled. Such changes will not take effect.
複製程式碼

搜了下Issues,有相同的問題。官方技術大佬是怎麼回覆的,不過具體原因還有待研究...

官方技術大佬的回覆

ignoreWarning = true 這裡設定為忽略警告,再次 graldew tinkerPatchDebug

成功之後有個patch_signed_7zip.apk

patch_signed_7zip.apk

下載併合成補丁

可以使用命令列將補丁包傳送到手機。 adb push ./app/build/outputs/apk/tinkerPatch/debug/patch_signed_7zip.apk /storage/sdcard0/

不過這裡執行失敗了 `adb server is out of date. killing... CreateProcess failure, error 2

  • failed to start daemon * error:` 試了一大堆方法,無果...

好吧!手動拷貝到手機檔案管理根目錄下。 再次開啟Tinker-Demo 點選LOAD PATCH 按鈕 過了2-3s 出現Toast 提示

Toast 提示

返回,再進入... 沒反應 這裡注意,必須要殺掉程式,再次進來才能成功載入patch包的程式碼。 手動殺掉,或者點選KILL SELF 按鈕

hello, Tinker

完成修復

寫在後頭

各個框架各有優劣,Tinker 官方在文件中也指出其不足之處:

Tinker經過幾次全量上線,也發現了一些熱補丁的問題。有以下的一些優化工作尚未完成: 1. 支援四大元件的代理; 2. Crash 啟動保護;

道阻且長,目前Tinker 還只能是替換類、資源和so 檔案等,如果支援了四大元件的代理,也許所有的非重大版本更新都可以用熱修復來實現了。

推薦閱讀:Android 熱修復 - 各框架原理學習及對比
Amigo學習(一)解決使用中遇到的問題比

記錄在此,僅為學習!
感謝您的閱讀!歡迎指正!
歡迎加入 Android 技術交流群,群號:155495090。

相關文章