1. 程式人生 > >熱修復And外掛化學習總結

熱修復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 (測試中...)    

   如何使用

RocooFixs

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試用。