Android熱修復(Hot Fix)案例全剖析(一)

lvxfcjf發表於2021-09-09

說到熱修復技術,我們不得不先談一下什麼是冷修復。

冷修復

當我們發現上線的應用APK存在Bug,我們透過釋出新的應用APK,去替換舊的應用APK,以達到解決Bug的目的,但是這樣做存在很大的缺點,需要使用者二次下載APK,浪費使用者流量,費時、費力、使用者體驗差。

熱修復

當我們發現上線的應用APK存在Bug,我們在使用者使用過程中就把Bug修復了,優點是其過程中使用者不需要把應用程式停止、解除安裝、重新安裝、重啟,大大改善了使用者體驗。

熱修復原理解析

通常作為一款應用,最容易出現Bug的地方,是java程式碼。我們知道Oracle的套路,java原始檔是被編譯成.class檔案,用ClassLoader載入.class;而安卓使用Dalvik/ART虛擬機器,由於版權問題,谷歌把.class編譯成了dex檔案,並透過ClassLoader載入dex。我們的熱修復方案,其實就是基於我之前部落格中講到的Android dex多分包方案實現的。想學習瞭解Android Dex多分包技術的童鞋,請點選連結檢視:

為了便於大家形象具體的理解熱修復技術的流程,我給大家畫一幅原理圖。

圖片描述

待修復專案搭建

明白了熱修復的流程以後,為了方便給大家演示熱修復的流程,我們首先新建一個含有Bug的專案,該專案有一個頁面,頁面中包含兩個按鈕,一個按鈕點選後會執行錯誤未修復的程式碼,另一個按鈕點選後執行熱修復操作。

MainActivity程式碼如下:

public class MainActivity extends Activity {
    Button btnOpen, btnModify;
    NullTest nt = new NullTest();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnOpen = (Button) findViewById(R.id.btn_open);
        btnModify = (Button) findViewById(R.id.btn_modify);
        btnOpen.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                nt.printAbcLength(MainActivity.this);// 執行計算
            }
        });

        btnModify.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                castielFixMethod();// 呼叫熱修復方法
            }
        });
    }
}

出錯的NullTest計算工具類:

public class NullTest {
    int a = 8;
    int b = 0;// 故意設定為0

    public void printAbcLength(Context context) {
        // 很明用8除0,一定會導致java.lang.ArithmeticException: / by zero異常
        Toast.makeText(context, "count result:" + (a/b), Toast.LENGTH_LONG).show();
    }
}

佈局檔案程式碼:



    

OK,專案原始碼開發到此為止,接下來,我們透過使用ant命令,對該專案進行多分包構建,這次我們一共構建了兩個dex包,特地把出錯的NullTest類放到classes2.dex中去,為的就是方便後面的熱修復。

<!-- 構建多分包dex檔案 --&gt

    <!-- 主包包含class檔案列表 --&gt<!--  --&gt

主包配置檔案清單:

com/castiel/demo/MainActivity.class

完成以上所有操作後,我們將構建出來的APK安裝到手機上,然後測試,點選執行操作按鈕,發現專案崩潰並閃退。

圖片描述

開發熱修復補丁dex檔案

1.發現並修改Bug

public class NullTest {
    int a = 8;
    int b = 1;// 這裡我們將出錯的0改為1

    public void printAbcLength(Context context) {
        Toast.makeText(context, "count result:" + (a/b), Toast.LENGTH_LONG).show();
    }
}

2.生成補丁dex檔案 

修改錯誤程式碼後,我們clean一下專案,在專案的bin目錄中找到生成的新的NullTest.class檔案,連同該檔案的包目錄一併複製出來(注意其他的類檔案通通去掉),這裡我複製到桌面上的castiel資料夾中,同時在該資料夾中新建一個castieloutput資料夾,用於稍後存放編譯的dex檔案。

圖片描述

然後在cmd命令列中,利用SDK的dx工具編譯生成新的dex檔案

圖片描述

成功後,我們將生成的dex檔案反編譯,可以看到新的修復補丁檔案已經將0改為1

圖片描述

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3486/viewspace-2808278/,如需轉載,請註明出處,否則將追究法律責任。

相關文章