Nuwa熱修復實現

既然前面的AndFix暫時還不可行,那隻能投奔QQ團隊的Nuwa了。按照開發思路,本應先講講Nuwa的優缺再講講其使用的,但基於對Nuwa的瞭解不夠深厚,我們還是先看看其具體使用吧。雖然網上已經提供了很多使用解說,但此刻僅求站在低點角度幫到大家填下小坑。

添加Nuwa插件

1.編輯工程的根build.gradle文件

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
        classpath 'cn.jiajixin.nuwa:gradle:1.2.2'
    }
}

2.在app的build.gradle中添加依賴SDK

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'cn.jiajixin.nuwa:nuwa:1.0.0'
}

apply plugin: "cn.jiajixin.nuwa"

此時引用 apply plugin: “cn.jiajixin.nuwa” 將有可能報異常Error:Cannot get property ‘taskDependencies’ on null object,其解決方法是將Gradle Plugin的版本降低至1.2.3就可以了,當然Gradle Version也要相應的降低至2.8。

設置plugin版本


使用Nuwa

1.在自定義Application當中初始化

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    Nuwa.init(this);
    Nuwa.loadPatch(this,"/sdcard/patch.jar")
}

這裏有個需要注意的地方是自定義Application必須是直接繼承自Application的類,如若自定義類AClazz繼承自Application,又自定義類BClazz繼承自AClazz並在註冊表聲明爲BClazz,那麼就會出現以下異常。也就是我們的初始化操作必須放在直屬繼承Application的AClazz當中。

java.lang.NoClassDefFoundError: Failed resolution of: Lcn/jiajixin/nuwa/Hack;
                                                     at archmages.github.hotfixsamples.HFApplication.<init>(HFApplication.java:17)
                                                     at archmages.github.hotfixsamples.MyApplication.<init>(MyApplication.java:12)
                                                     at java.lang.reflect.Constructor.newInstance(Native Method)

Caused by: java.lang.ClassNotFoundException: Didn't find class "cn.jiajixin.nuwa.Hack" on path: DexPathList[[zip file "/data/app/archmages.github.hotfixsamples-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
                                                     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                     at archmages.github.hotfixsamples.HFApplication.<init>(HFApplication.java:17) 
                                                            ... more

2.運行併成功安裝APK
運行過程中可能會中途報錯Execution failed for task ‘app:nuwaClassBeforeDexDebug’並在控制檯將會輸出以下信息

運行時有誤

爲解決以上遇到的問題,我們需要在app底下的build.gradle中加入multiDexEnabled true

defaultConfig {
    applicationId "archmages.github.hotfixsamples"
    minSdkVersion 14
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

順利運行並安裝APK完成之後可以在app\bulid\outputs\目錄下發現nuwa\debug\patch\目錄。此時我們需要把該目錄複製到本地任意位置下,譬如將該目錄直接放置到D:\目錄下,應該是D:\nuwa\debug\patch\。目錄必須是醬紫,否則將無法生成.jar補丁文件。

nuwa目錄

補丁文件.jar生成

1.移動hash.txt文件
在複製好nuwa目錄後,若將當前apk視爲存在bug的apk,這是我們要把nuwa\debug\目錄下的hash.txt文件複製到本地目錄D:\nuwa\debug\下。

2.生成補丁命令
這裏小編建議是在執行命令前都應該先Clean以下項目(app\bulid\outputs\ 內容將重置)。之後執行命令只要在項目的根目錄下直接執行就可以了(根目錄下存在gradlew與gradlew.bat兩個文件)。

  • Mac:gradlew clean nuwaDebugPatch -P NuwaDir=D:\nuwa
  • Windows:gradlew.bat clean nuwaDebugPatch -P NuwaDir=D:\nuwa

執行命令過程也未必是一帆豐順,或許我們會遇到如下問題$ANDROID_HOME is not defined導致失敗跳出命令。

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:nuwaDebugPatch'.
> $ANDROID_HOME is not defined

* Try:         
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED   

以上問題比較好解決,我們給‘ANDRIOD_HOME’設置下SDK的目錄就OK了,命令如下。之後再次執行生成.jar補丁的命令就沒什麼問題了。如果有發現執行命令結果提示成功但是沒有生成補丁文件的,請確保以上操作無誤或已經正確修改了相關BUG內容

成功執行命令並在app\bulid\outputs\nuwa\debug目錄下生成補丁文件patch.jar的親,只要把其放置到初始化時指定的補丁獲取位置下重啓APP即可生效,當然這只是本地操作,最終還是得通過下載實現的。

set ANDROID_HOME=D:\個人SDK根目錄

聊聊Nuwa情況

回到一開始說的,講完整個引用過程後,就該講講Nuwa的其他瑣事了。這裏得先聲明下只是個人見解噢,後面依然會根據使用情況繼續更新本塊內容[20160915]。

1. 手機兼容性問題
真機測試中發現HTC6.0.1與MEIZU5.1的手機均無法實現熱修復功能且異常退出。5.0以上的機子部分不行就比較尷尬了,如果對兼容性沒有太概要求的,還是先將targetSdkVersion值修改爲22壓壓驚先吧。

2. 新增或修改內容無效
順利引用後小編試過增刪圖片資源,class文件以及.xml文件,結果都能在補丁文件中達到操作效果。但奇怪的是,如果噹噹只是編輯已有.xml文件內容,卻無法生成補丁文件,這是爲何?這裏得感謝我的同事wneng,因爲這是他發現的問題,並且還從hash.txt文件當中分析爲何沒能生成補丁文件的緣故,發現其中指定需要被生成爲補丁的內容是有限制的,所以才無法生成補丁文件以及修復效果。具體有興趣的親可以繼續探索下。

3. 對比AndFix
可修復文件類型更廣闊,AndFix只能對應class文件做修復工作;執行過程並不比AndFix複雜;兼容性處理相對上比AndFix要穩定得多;需要重啓APP應用才能生效,AndFix則是當次生效;除此以外Nuwa本身也還有很多不完善的地方,可參考下面內容深入瞭解。

4. patch.jar影響之源遠流長
由於生成的補丁文件具有針對性,所以向上發佈的項目源碼必須另做存儲處理。使用Git的儘量拓展到hotFix分支上,或者在發佈分支上做Tag標記,另外須留意各補丁的版本與加載控制,否則極有可能影響應用程序的後繼研發。

這裏寫圖片描述

5. 聽說能支持 gradle1.5.0,
標識只是爲了跟上2.0的Instance Run。所以必須立刻馬上拿下demo嘗試一番,結果發行運行成功後並沒有在build下出現傳說中的nuwa目錄,然後只得乖乖的將gradle版本降會1.2.3。

更多參考

發佈了50 篇原創文章 · 獲贊 4 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章