Andfix熱修復技術使用


AndFix,全稱是Android hot-fix。是阿里開源的一個Android熱補丁框架,允許APP在不重新發版本的情況下修復線上的bug。支持Android 2.3 到 6.0。

andfix的github地址: https://github.com/alibaba/AndFix

AndFix的集成使用請參照demo (AndFix-Demo,A demo about using AndFix 0.5.0) https://github.com/linghu88/hotfix-andfix

一、andfix使用
  1. 首先添加依賴
    compile 'com.alipay.euler:andfix:0.3.1@aar'

  然后在Application.onCreate()中添加以下代碼:
    patchManager = new PatchManager(context); //初始化補丁包管理器
    patchManager.init(appversion); //版本 String appversion= getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
    patchManager.loadPatch(); //加載所有補丁
  注意每次appversion變更都會導致所有補丁被刪除,如果appversion沒有改變,則會加載已經保存的所有補丁。
  然后在需要的地方調用PatchManager.addPatch()方法加載新補丁,比如可以在下載補丁文件之后調用。

  如果你使用混淆,你要保存mapping.txt,這樣的話你在新版本的構建是就可以借助 "-apply mapping” 來使用它了。
  混淆需要加入:
    -keep class * extends java.lang.annotation.Annotation
    -keepclasseswithmembernames class * {
      native <methods>;
    }
    -keep class com.alipay.euler.andfix.** { *; }

  2. 打補丁包,首先生成一個apk文件,然后更改代碼,在修復bug后生成另一個apk。
    通過AndFix官方提供的補丁包創建工具apkpatch生成一個.apatch格式的補丁文件,需要提供原apk,修復后的apk,以及一個簽名文件。
    可以直接使用命令apkpatch查看具體的使用方法。
    使用示例:apkpatch -o D:/Patch/ -k debug.keystore -p android -a androiddebugkey -e android f bug-fix.apk t release.apk
    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.
  有時候你的團隊成員可能會fix各自的bug,這個時候就會有不止一個補丁文件.apatch。這種情況下,可以用這個工具merge這些.apatch文件:
    usage: apkpatch -m <apatch_path...> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
    -a,--alias <alias> keystore entry alias.
    -e,--epassword <***> keystore entry password.
    -k,--keystore <loc> keystore path.
    -m,--merge <loc...> path of .apatch files.
    -n,--name <name> patch name.
    -o,--out <dir> output dir.
    -p,--kpassword <***> keystore password.


  3. 通過網絡傳輸或者adb push的方式將apatch文件傳到手機上;
  4. 然后運行到patchManager.addPatch(path)的時候就會加載補丁。//path:補丁文件下載到本地的路徑。
  加載過的補丁會被保存到data/packagename/files/apatch_opt目錄下,所以下載過來的補丁用過一次就可以刪除了。

  注意:每次產生的apatch文件的名字如果是相同的,結果會導致只有第一次的補丁能生效。只有每次名字不同才能加載,log中應該也有提示。

  如果使用andfix官方提供的demo的使用步驟:
  1. 導入samplesI/AndFixDemo進你的IDE,給AndFixDemo添加AndFix(library project 或者 aar)的依賴。  
  2. build 工程,保存應用為1.apk,然后將該apk安裝到手機或者模擬器上。
  3. 修改com.euler.test.A,作為Fix后的包。
  4. build 工程,保存應用為2.apk
  5. Use apkpatch tool to make a patch. 使用apkpatch 工具制作一個補丁文件。
  6. Rename the patch file to out.apatch, and then copy it to sdcard.重命名補丁文件為out.apatch ,然后將它拷貝到sdcard上。
  7. 運行1.apk然后查看log

二、andfix原理:
  apkpatch將兩個apk做一次對比,然后找出不同的部分。可以看到生成的apatch了文件,后綴改成zip再解壓開,里面有一個dex文件。通過jadx查看一下源碼,里面就是被修復的代碼所在的類文件,這些更改過的類都加上了一個_CF的后綴,並且變動的方法都被加上了一個叫@MethodReplace的annotation,通過clazz和method指定了需要替換的方法。然后客戶端sdk得到補丁文件后就會根據annotation來尋找需要替換的方法。最后由JNI層完成方法的替換。如果本地保存了多個補丁,那么AndFix會按照補丁生成的時間順序加載補丁。具體是根據.apatch文件中的PATCH.MF的字段Created-Time。
AndFix通過Java的自定義注解來判斷一個方法是否應該被替換,如果可以就會hook該方法並進行替換。AndFix在ART架構上的Native方法是art_replaceMethod 、在X86架構上的Native方法是dalvik_replaceMethod。他們的實現方式是不同的。對於Dalvik,它將改變目標方法的類型為Native同時hook方法的實現至AndFix自己的Native方法,這個方法稱為dalvik_dispatcher,這個方法將會喚醒已經注冊的回調,這就是我們通常說的hooked(掛鈎)。對於ART來說,我們僅僅改變目標方法的屬性來替代它。

三、 安全驗證:
  文件的簽名驗證:AndFix對apatch文件簽名做了是否和應用的簽名是同一個的驗證,不是的話就不加載該補丁。
指紋optimize file驗證:為了防止有人替換掉本地保存的補丁文件,所以要驗證MD5碼。SecurityChecker類里面也已經做了驗證處理,但是這個MD5碼是保存在sharedpreference里面,如果手機已經root那么還是可以被訪問的。


四、優缺點:
  優點:
  1. 不需要重啟APP即可應用補丁,對用戶透明無感知;
  2. 能滿足快速修復問題。
  缺點:
  1. 無法添加新類和新的字段;
  2. 需要使用加固前的apk制作補丁,但是補丁文件很容易被反編譯,也就是修改過的類源碼容易泄露。
  3. 使用加固平台可能會使熱補丁功能失效(在360加固提了這個問題,未驗證)。如果你使用了,軟件加固比如 Bangcle,為了生成補丁文件,你最好使用為經過加固的apk.使用這些加固,很可能使熱補丁失效。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM