天天看點

架構日記(八)Android熱修複架構的內建

至于AndFix和SoPhix的原理,機制我就不贅言了,網上大把的資料,阿裡雲上也有非常詳細的說明。本文注意介紹內建的步驟

一· AndFix內建

config.gradle

dependencies = [
            ...
            andfix                  : "com.alipay.euler:andfix:[email protected]"

    ]
           

base.gradle

api rootProject.ext.dependencies["andfix"]
           

MyApplication

public class MyApplication extends BaseApplication {

    private RefWatcher refWatcher;
    private PatchManager mPatchManager;


    @Override
    public void onCreate() {
        super.onCreate();
        refWatcher= setupLeakCanary();
        mPatchManager = new PatchManager(this);
        mPatchManager.init("1.0");
        Log.d("TAG","inited");

        mPatchManager.loadPatch();
    }

    private RefWatcher setupLeakCanary() {
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return RefWatcher.DISABLED;
        }
        return LeakCanary.install(this);
    }

    public static RefWatcher getRefWatcher(Context context) {
        MyApplication leakApplication = (MyApplication) context.getApplicationContext();
        return leakApplication.refWatcher;
    }
}
           

 MainActivity的點選事件中一個彈出Toast的函數作為測試熱修複的測試函數

分别是

private void showMsg(){
    Toast.makeText(this,"new",Toast.LENGTH_LONG).show();
}
           
private void showMsg(){
    Toast.makeText(this,"old",Toast.LENGTH_LONG).show();
}
           

接下來就是生成jks簽名檔案(AndroidStudio)

分别打出新老兩個簽名包

放在同一個檔案夾下面,如圖所示

架構日記(八)Android熱修複架構的內建

接下來要做的就是下載下傳apkpatch-1.0.3.jar工具包,内不包含了shell和bat腳本

本文是MAC下,采用shell腳本

執行生成更新檔包指令:

./apkpatch.sh -f new.apk -t old.apk -k mytest.jks -p 12205226 -a key0 -e 12205226 -o patch
           

注意:由于指令行中寫了new.apk  &&   old.apk,是以請務必将打包出來的包名修改名稱,與此同名

大家對比簽名檔案就知道哪些是參數了

signingConfigs{
    config {
        keyAlias 'key0'
        keyPassword '12205226'
        storeFile file('/Users/mac/Desktop/mytest.jks')
        storePassword '12205226'
    }
}
           

提供一些apkapatch指令的說明:

usage: apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
 -a,--alias <alias>     keystore entry alias.
 -e,--epassword <***>   keystore entry password.
 -f,--from <loc>        new Apk file path.
 -k,--keystore <loc>    keystore path.
 -n,--name <name>       patch name.
 -o,--out <dir>         output dir.
 -p,--kpassword <***>   keystore password.
 -t,--to <loc>          old Apk file path.
           

指令執行完後會在patch檔案生成

架構日記(八)Android熱修複架構的內建

如果大家感興趣呢可以去研究一下android反編譯的三個套裝  dex2jar工具可以将diff.dex專為 diff.dex.jar可以檢視内部源碼,會有标簽辨別出需要修複的函數名稱。

主要是看.apatch檔案,這個就是更新檔封包件 根據代碼中加載的名稱可以修改.apatch的名稱

mv new-86.......0.apatch yourname.apatch 

 記下來安裝old.apk

adb install old.apk

然後push 更新檔檔案到sd卡上,當然了,也可以通過伺服器下載下傳更新檔檔案

adb push ./out.apatch /sdcard

我的代碼中的更新檔檔案名稱定義為out.apatch 名稱自行修改

接下來看調用的代碼其實也非常簡單

private void loadPatch(){
        String patchFileString = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + APATCH_PATH;
        if(new File(patchFileString).exists()){
            try {
                MyApplication.mPatchManager.addPatch(patchFileString);
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.d("TAG",patchFileString);
        }
//        File f = new File(this.getFilesDir(), DIR + APATCH_PATH);
//        if (f.exists()) {
//            boolean result = new File(patchFileString).delete();
//            if (!result) {
//                Log.e("TAG", patchFileString + " delete fail");
//            }
//        }
    }
           

APATCH_PATH 的值是 “./out.apatch”

操作步驟  先安裝old.apk點選事件show出來的是old  當我們push之後,執行loadPatch方法後,在點選就可以發現彈出的是new了

AndFix的原理上還是有缺陷的,涉及到虛拟機,而虛拟機以Android5.0為分界線有存在差異,特别是後面的廠家都有訂制是以對于适配問題是一個非常挑戰和頭疼的事情,是不是有的小夥伴發現放到sdcard上死活不行,這就是不同的手機檔案系統差異性造成的,建議使用網絡下載下傳apatch檔案在addPatch()。

對于AndFix的相容性問題。阿裡給出了加強版的方案SoPhxi-HotFix方案。下一篇繼續~

apatch工具下載下傳位址   https://download.csdn.net/download/qq_20369621/12488056