runFix
熱修復勃救,支持Class類(dex文件)碍讨,SO(so庫文件夾),資源文件(apk文件)修復剪芥。
需求背景:
隨著用戶量的上升垄开,對一個APP的穩(wěn)定性要求也越來越高,而在代碼的世界中即便是萬分小心税肪,還是會出現各種意料之外的異常溉躲。對于異常的發(fā)生如何快速定位和解決是對程序員的重大考驗。
但若每次一發(fā)生異骋嫘郑或修改一些簡單的代碼锻梳,就去更新一次APP,這不僅僅增加了程序員自身的工作量净捅,最關鍵的是十分影響用戶體驗疑枯,那么如何在用戶無感知的情況下修復已知異常呢?runFix熱修復便是一個很好的解決方案蛔六。
引入runFix插件:
- 在根gradle文件中引入jitpack倉庫:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
- 在工程gradle文件中引入MaoKePlayer插件
dependencies {
implementation 'com.github.zrunker:runFix:v1.0'
}
執(zhí)行修復 - RunFix:
RunFix類提供了本地和網絡兩種修復方式荆永,相關API如下:
-
修復網絡文件:
// url待修復資源的網絡鏈接 RunFix.getInstance(context).fixUrl(String url); // urls待修復資源的網絡鏈接集合 RunFix.getInstance(context).fixUrlList(ArrayList<String> urls);
注意:默認下載url是通過get的方式進行下載。
-
修復本地文件:
// filePath待修復資源文件的本地地址 // class -> dex文件 // so -> armeabi国章,armeabi-v7a具钥,x86,mips液兽,arm64- v8a骂删,mips64,x86_64文件夾 // res -> apk文件 RunFix.getInstance(context).fixFile(String filePath);
-
修復本地文件夾:
// dirPath待修復資源的本地文件夾地址 RunFix.getInstance(context).fixDir(String dirPath);
-
修復默認文件夾(推薦):
RunFix的默認修復文件夾地址為${applicationid}/fix目錄四啰,所以把待修復資源文件放入該目錄下宁玫,執(zhí)行如下方法就能夠完成修復功能:
// 執(zhí)行待修復資源默認目錄 RunFix.getInstance(context).fix();
補充:
// 獲取待修復資源默認目錄地址 RunFix.getInstance(context).fixDefaultDir();
待修復文件生成:
runFix支持Class類,SO庫以及資源文件的修復柑晒,但三種類型文件修復需要包裝成特定格式文件才行欧瘪。
- Class類的修復:需要將待修復的Class類文件一起打包成dex文件。
- SO庫的修復:需要將待修復的so庫放入特定的armeabi匙赞,armeabi-v7a佛掖,x86,mips罚屋,arm64- v8a苦囱,mips64,x86_64文件夾下脾猛。
- 資源文件的修復:需要將APP中所有資源文件一起打包成apk文件撕彤。
假如將所有待修復文件放入云端提供修復下載,那么該如打包出不同類型的修復文件呢?
一. 修復Class類文件【DEX文件】:
如何打DEX文件包羹铅?
如果工程遇到屬于類文件代碼導致的BUG蚀狰,那么就需要修復類文件,并將修復之后的類文件打包成DEX文件职员,上傳至之前設置好的云平臺麻蹋,那么如何打包成DEX文件呢?
1焊切、Java文件編譯成Class文件扮授,可以使用AS 執(zhí)行 Make Project,或者使用javac命令執(zhí)行Java文件专肪。
-
編譯前:
2.png -
編譯后:生成build文件目錄刹勃,而class文件便在該build文件目錄內。
3.png
找到編輯后的class文件嚎尤,build/intermediates/javac/debug/classes/....不同AS版本可能目錄不一致荔仁。
將編輯之后的class文件,連同目錄一起復制到一個單獨的目錄下芽死。
例如:修復的文件是在com.baidu.runFix.MainActivity乏梁,那么就將com文件目錄拷貝到一個單獨目錄用于打包DEX文件。
例如將其放置桌面fix目錄下:
2关贵、使用dx工具將class文件打包成dex文件遇骑。
找到Android SDK目錄,該目錄中將會有dx工具坪哄,一般位置是/Users/zoufengli01/Library/Android/sdk/build-tools/28.0.3/dx质蕉。
使用shell終端势篡,執(zhí)行dx命令將會生成DEX文件:
/Users/zoufengli01/Library/Android/sdk/build-tools/28.0.3/dx --dex --output=/Users/zoufengli01/Desktop/fix/classes-fix-1.dex /Users/zoufengli01/Desktop/fix
<!--dx --dex --output-->
classes-fix-1.dex就是打包之后的DEX文件翩肌,也是需要上傳至云端的dex補丁。
二禁悠、修復資源文件【APK文件】:
只保留APP工程中的資源文件(如:res目錄中文件)念祭,將其他文件全部刪除,然后將剩下文件打包成APK文件碍侦,上傳至云端提供下載粱坤。
三、修復so庫文件【ZIP文件或文件夾】:
如何打包SO庫瓷产?
將JNI代碼編譯成So庫站玄,一般情況下都是使用NDK進行編譯,通常是直接使用NDK執(zhí)行腳本命令濒旦,例如:音視頻播放器【NA】一文中是使用Shell命令進行編譯株旷。
另外如果是自己開發(fā)打包成SO庫的話,采用Android Studio+CMake也是十分方便,只需要簡單配置CMakeLists.txt:
cmake_minimum_required(VERSION 3.10.2)
project("test")
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
目錄結構如下:
其中native-lib.cpp便是需要編譯的c++文件晾剖。
編譯好代碼之后锉矢,保存,點擊編譯按鈕齿尽,便會自動生成相應CPU架構SO庫:
之后將這些編譯之后的so庫打包上傳到云端即可沽损,注意:打包時要將整個CPU架構文件夾都一起打包,而不能只打包單一的so庫循头。
例如:將libs文件夾打包(將其壓縮成zip包)上傳至云端提供下載绵估。