Android熱更新之Nuwa實踐
今天給大家講一下熱更新之Nuwa實踐。
熱更新的框架有很多,比如AndFix、HotFix、Dexposed以及Nuwa,在考慮相容性和功能需求之後我還是選擇了Nuwa,因為這個框架可以新增類和欄位,並且相容到Android6.0系統。
現在市面上的熱更新框架基本原理都是classloader,也就是類載入器,這也就限制了我們不可以修改資原始檔,如圖片佈局等,有這方面需求的小夥伴還要想其他辦法,比如動態佈局。
首先你的開發工具必須是Android Studio,因為在打jar包時需要使用.gradle檔案。其次電腦上要有一個本地的git庫,以方便管理新舊版本,使用git命令較為方便,要下載nuwa庫,並且user library到你的專案中,不會這個步驟的同學請自行百度,在這裡推薦一個github上的專案,裡面有整合好的nuwa庫。
https://github.com/jasonross/Nuwa
假設我們已經建立好一個專案,並且成功整合nuwa,現在我們需要一個git,然後新建一個本地版本庫,選擇一個合適的檔案路徑,輸入以下git命令:

mkdir hotfix 是建立名為hotfix的本地版本庫,cd hotfix是定位到版本庫,pwd是輸出版本庫位置,如果你是在windows系統上使用,為了避免不可測問題,請保證路徑中沒有特殊符號及中文。
建立好庫後要使用命令將其變成git可管理的版本庫:

建立成功後,會發現資料夾中出現一個.git檔案,如果你的看不到,那可能是因為這個檔案是隱藏的,使用ls -ah命令試試看。
版本庫建立成功了,現在我們要做的就是將剛剛建立的專案匯入到版本庫中,拷貝你的專案到hotfix資料夾中,並且使用以下命令:

git add 後面跟著的是你的專案名稱,在add過程中會出現一系列waning警告,不要理,只要不出error就好。add成功後,再提交一次程式碼,如果沒有問題就你的專案就匯入成功了:

提交過程中又會出現一系列warning,不用理。這裡需要注意的是-m後面是你每次提交的註釋,不可為空,為了方便以後維護,希望大家可以寫清本次提交原因。
成功將專案匯入,下面我們就要開始寫程式碼了,如果你的專案是從剛剛推薦的github上拉下來的,那你專案中應該有完整程式碼,不是的童鞋請跟我一步步完成程式碼。
熱更新原理
熱更新的原理大概就是從伺服器拉取一個補丁檔案,然後用類載入器載入這個補丁中的類,如果我們想要實現在專案開始時就加載出這個補丁檔案,那麼載入補丁的操作就要放在Application類中實現,程式碼如下:
import android.app.Application; import android.content.Context; import android.os.Environment; import cn.jiajixin.nuwa.Nuwa; public class NuwaApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); Nuwa.init(this); Nuwa.loadPatch(this, Environment.getExternalStorageDirectory().getAbsolutePath().concat("/patch.jar")); } }
很簡單,nuwa框架已經封裝好了很多操作,我們只需要呼叫就好,loadpatch方法中的引數是補丁檔案的位置,應該從伺服器動態獲取檔案,並存儲到sdcard指定專案專用目錄,在這裡我們是測試demo,就簡單的固定好jar檔案位置,sdcard根目錄。在這裡提醒一下粗心的同學,不要忘記在Manifest檔案中配置Appliction。
其他只需要在MainActivity中顯示要輸出的文字,這裡我們將文字單放在一個類中,以便改變:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; import cn.jiajixin.nuwasample.Hello.Hello; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.textview); textView.setText(new Hello().say()); } } public class Hello { public String say() { return "hello world"; } }
最後,我們要在剛剛建立的本地版本庫上建立一個bugfix分支,hotfix資料夾中開啟git,並輸入以下命令:

使用android studio執行專案到手機上,成功執行之後,會在專案的目錄下建立一個nuwa資料夾,如果你是自己建立的專案,那麼路徑應該是appild/outputs/nuwa,如果你是匯入github上的專案,路徑應該是sampleild/outputs/nuwa,將nuwa資料夾拷貝到一個位置,比如桌面,我的是C:\Users\thinkpad\Desktop\nuwa,這個地方大家要注意,每個人拷貝的位置不同,一會使用時路徑一定要匹配。
現在使用git checkout bugfix命令切換到bugfix分支上,修改Hello類下面的輸出字串,如下:
public class Hello { public String say() { return "hello world I'm hotfix"; } }
改好之後我們就要通過git命令呼叫.gradle來打一個jar包,千萬注意,不要執行bugfix分支上的專案。
如果你是自己新建的app,要在專案中新建一個名為extras的資料夾:

在資料夾中有兩個配置檔案,一個是名為hack的空java類,另一個檔案裡面寫好了一段使用dx封裝jar包的命令:

配置好這兩個檔案後,再在hotfix中開啟git,在git中輸入:
./gradlew clean nuwaQihooDebugPatch -P NuwaDir=C:/Users/thinkpad/Desktop/nuwa
這裡有兩點需要注意,NuwaDir=後面跟著的路徑就是剛剛master分支執行專案時,生成的nuwa資料夾,具體路徑要看大家拷貝的地址。還有就是因為這個命令是呼叫.gradle檔案,我們的版本庫是兩層資料夾,需要cd進入到Nuwa專案資料夾中執行該命令:

執行成功後你會在你想專案目錄下看到一個名為patch.jar的檔案,如果你是新建的專案,具體路徑應該為app\build\outputs\nuwa\qihoo\debug\patch.jar
如果你是從github上拉下來的專案,路徑應為
sample\build\outputs\nuwa\qihoo\debug\patch.jar
將上面生成的jar檔案匯入到手機sdcard檔案根目錄,你可以選擇通過電腦拷貝或者使用安卓命令:
adb push E:hotfix\Nuwa\app\build\outputs\nuwa\qihoo\debug\patch.jar /sdcard/
大家寫了這麼久,終於到了收穫的時候,現在先退出剛剛在手機上安裝的master分支上的專案,徹底退出,殺死程序。然後再重新進入,有沒有驚喜的發現之前的"hello world"變成了我們修改的"hello world I'm hotfix"?這就實現了補丁方式的熱更新,而且使用nuwa框架是可以新建類的哦,雖然不能更改資原始檔,但是配合動態佈局使用還是能實現大部分需求的,如果要修改資原始檔可以試試微信熱修復Tinker。
【附錄】

資料圖
需要資料的朋友可以加入Android架構交流QQ群聊:513088520
點選連結加入群聊【Android移動架構總群】: 加入群聊
獲取免費學習視訊,學習大綱另外還有像高階UI、效能優化、架構師課程、NDK、混合式開發(ReactNative+Weex)等Android高階開發資料免費分享。