熱修復And外掛化學習總結
說是心得,還不如說是相關資料整理,以便日後自己繼續學習查閱。
首先需要明確外掛化和熱修復的概念問題。
外掛化:是將功能程式碼做成APK的形式,想要讓新的程式碼生效,需要下載APK,載入APK中的新的程式碼和資源,這個過程需要重啟APP,重啟之後才能生效。
優勢:可解決65535方法數問題,可讓一個專案多個團隊並行開發獨立功能。
熱修復:是將新的程式碼打成jar/dex的形式,也需要下載jar/dex包,然後載入APP,一般來說,一旦載入馬上就能生效,無需重啟APP。
優勢:輕量化,對使用者透明化,修復起效快。
共同點:都採用了Java classloader載入類的原理,以及android 多dex分包原理。
外掛化開發框架:
############熱修復############
熱修復準備
原理分析
熱修復框架:
https://github.com/alibaba/AndFix alibaba(推薦)
https://github.com/dodola/RocooFix dodola(推薦)
https://github.com/dodola/AnoleFix dodola (測試中...)
如何使用
RocooFix支援兩種模式:
1、靜態修復某種情況下需要重啟應用。 (推薦使用)
2、動態修復,無需重啟應用即可生效。
使用方法:
//打補丁
RocooFix.init(this);
//方案1:靜態啟用,一般在Application里加載補丁
/**
* 從Assets裡取出補丁,一般用於測試
*
* @param context
* @param assetName
*/
RocooFix.initPathFromAssets(Context context, String assetName);
/**
* 從指定目錄載入補丁
* @param context
* @param dexPath
*/
RocooFix.applyPatch(Context context, String dexPath);
//方案2:動態打補丁,立即生效,有效能問題,適用於補丁方法數較少的情況,建議在ART虛擬機器裡啟用該模式
/**
* 從Asset里加載補丁,一般用於本地測試
* @param context
* @param assetName
*/
RocooFix.initPathFromAssetsRuntime(Context context, String assetName) ;
/**
* 從指定目錄載入補丁
* @param context
* @param dexPath
*/
RocooFix.applyPatchRuntime(Context context, String dexPath) ;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
沒有加群的朋友可以下載上面的RocooFix_libs包跟著我一步步來做:
專案使用Android Studio開發,所以準備好翻牆工具下載依賴包!!!
一、新建Android專案 app
二、將上面下載檔案裡面的rocoo作為lib庫匯入
在app的build.gradle 裡面新增compile project(‘:rocoo’),也可以手動新增依賴。
三、下載下來的資料夾裡面還有個buildsrc檔案直接放到app專案平級目錄中(這個不用做任何操作)
到此我們的目錄結構為:
四:配置 根目錄裡面的 build.gradle檔案:
buildscript {
repositories {
jcenter()
maven {
url "http://dl.bintray.com/dodola/maven" //新增
}
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'org.jacoco:org.jacoco.core:0.7.4.201502262128' //新增
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
五、配置 app 裡面的build.gradle 檔案
apply plugin: 'com.android.application'
apply plugin: 'com.dodola.rocoofix' //新增
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.test.hotfixtest"
minSdkVersion 15
targetSdkVersion 23
versionCode 6
versionName "1.0"
}
//新增
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
/**
*
*必須新增
**/
rocoo_fix {
preVersionPath = '5'
enable = true
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile project(':rocoo')
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
preVersionPath = ‘1’ //注意:此項屬性只在需要製作補丁的時候才需開啟!!如果不需要製作補丁則需要去掉此項(其中的數值是前一個版本的版本號)
enable = true //注意:關掉此項會無法生成Hash.txt檔案
重點介紹一下 preVersionPath 的屬性:
rocoo_fix將製作補丁的步驟透明化,使用者無需手動備份hash.txt檔案,外掛會自動根據當前的versionCode生成hash.txt和mapping.txt檔案到指定目錄;
上一個版本釋出的時候版本號是1,那麼生成的檔案會放在app原始碼目錄/rocooFix/version1/[debug]|[release]的目錄下,如果需要製作補丁那麼在配置裡指定preVersionPath 屬性,它的值是上一個版本的版本號,這裡的值是1,
然後將build.gradle的versionCode的號碼修改,這裡修改成2,只要和之前的版本不同就可以,沒有具體值的要求
六、新增混淆程式碼(proguard-rules.pro):
-keep class com.dodola.rocoofix.** {*;}
-keep class com.lody.legend.* {*;}
- 1
- 2
- 1
- 2
七、新增測試程式碼:
新建一個Java類:
public class HelloHack {
public String showHello() {
return "rocoofix";
}
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
在建一個繼承Application的類:
public class RocooApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
//需要打補丁時開啟
RocooFix.init(this);
//測試從assets資料夾讀取補丁
RocooFix.initPathFromAssets(this, "patch.jar");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
八、執行專案看是否報錯。測試已沒錯。
九、生成 patch.jar 檔案
1、首先隨便修改下程式碼如:
public class HelloHack {
public String showHello() {
return "rocoofix——ok";
}
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
2、修改 app 專案中的build.gradle 檔案把 versionCode 版本修改一下,把preVersionPath值修改成versionCode沒修改之前的值。
然後執行專案就會在app目錄下生成app\rocoofix\version4\debug\patch.jar 了,得到這個檔案就算成功了。
最後我們就可以隨便測試補丁了,放在sd目錄或者assets檔案下,關閉補丁RocooFix.init(this)
執行沒修改前的程式碼看看程式是否變了。
ps:實際專案中,還需要將補丁從伺服器下載到使用者客戶端,這個過程無非就是http請求,其中邏輯自行定製。
ps:這裡做好心理準備補丁在有些機型會失效,目前測試MI 2S 4.4.4系統 成功。後面還會帶來阿里的框架AndFix試用。