zoukankan      html  css  js  c++  java
  • 听说”双11”是这么解决线上bug的

    听说”双11”是这么解决线上bug的

                                --Android线上热修复的使用与原理

    预备知识和开发环境

    Android NDK编程

    AndFix浅析

    Android线上热修复的原理大同小异。这里仅仅针对眼下最火的框架AndFix进行解说。主要从AndFix的使用原理以及优缺点三个方面进行阐述。

    使用方式

    介绍

    AndFix是一个AndroidApp的在线热补丁框架。

    使用此框架。我们可以在不反复发版的情况下,在线改动App中的Bug。AndFix就是 “AndroidHot-Fix”的缩写。

    就眼下来说,AndFix支持Android2.3到6.0版本号,而且支持arm与X86系统架构的设备。完美支持Dalvik与ART的Runtime。眼下已经应用到支付宝上。是比較成熟的hot-fix框架。

    AndFix 的补丁文件是以.apatch 结尾的文件。(来源:网络)

    接入流程图:


    接入步骤

    1) Maven或Gradle下载aar或直接引入源代码

       

    Maven:
    <dependency>
        <groupId>com.alipay.euler</groupId>
        <artifactId>andfix</artifactId>
        <version>0.3.1</version>
        <type>aar</type>
    </dependency>
    Gradle:
    dependencies {
        compile 'com.alipay.euler:andfix:0.3.1@aar'
    }
    

    2) 初始化PatchManager

    patchManager = new PatchManager(context);
    patchManager.init(appversion);//current version
    

    3) 载入补丁包

    patchManager.loadPatch();

    4)存在新补丁包

    patchManager.addPatch(path);//path of the patch file that was downloaded

    5)删除全部补丁包

    patchManager.removeAllPatch();

    制作apatch文件

     1)  工具 :apkpatch(Github下载)

     2)  使用方式

      打补丁命令:

      

    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.
    
      合并补丁命令:

    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.
    

      举例:

       两个apk文件,一个有问题,一个把问题攻克了,如图:

      

        打开cmd,cd到apktool所在路径。运行例如以下命令:

      回车,在C:UsersxiayongDesktopHotFixTest esult文件夹下生成例如以下文件

      

       当中。out.apatch便是我们须要的补丁文件。

    代码混淆

    PS:官方建议使用-applymapping 来打混淆包。保证两次混淆一致。
    -keep class * extends java.lang.annotation.Annotation
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    

    疑问

    1、.apatch 文件下载下来以后的存储位置应该在哪里?

    2、.apatch文件删除了还有效果吗?

    3、hot-fix的安全性怎么保证?

    带着疑问,请看原理分析~


    原理剖析

    原理图:


    一句话说明:找到问题安装包中出错的Method。用.apatch文件里修复过的Method进行替换。

    举个栗子:

    演示代码来源:https://github.com/THEONE10211024/HotFixDemo

    .apatch文件:

    .apatch文件是hot-fix的关键,那么.apatch文件又是一个什么东西呢?以下,我们来重点分析一下.apatch文件。

    1.  apatch文件实际上是一个压缩文件

    解压apatch文件,一探到底:


    包括了一个dex文件和一个目录。先看看目录里都有什么文件



    重点是PATCH.MF文件。用记事本打开。



    AndFix首先会读取这个文件中面的东西。

    保存在Patch类的一个对象里,备用。

    再看看classes.dex文件。

    用反编译工具反编译后,我们会看到类似例如以下的文件:



    分析好了apatch文件,接下来我们一步步看AndFix是怎么修复的。

    把AndFix接入自己的APP仅仅须要四行代码:

    mPatchManager = new PatchManager(this);
    mPatchManager.init("1.0");
    mPatchManager.loadPatch();
    mPatchManager.addPatch(patchFileString);
    

    1、mPatchManager = new PatchManager(this);

    初始化一些以后会使用的对象。

    (详见代码)

    2、mPatchManager.init("1.0");

    首先推断传入的版本号号“1.0”是否是已有补丁相应的版本号号。

    不是,说明APP版本号已经升级。须要把老版本号的clean掉。然后初始化补丁包:遍历APP的私有文件夹(/data/data/xxx.xxx.xxx/file/apatch)下全部文件,找到以“apatch”为后缀的文件。解析文件->读取文件必要信息(主要是PATCH.MF中)->存放在mPatchs(类型:SortedSet<Patch>)中。

    3. mPatchManager.loadPatch();

    遍历mPatchs,针对每一个补丁文件:安全校验->解析dex->载入类->找到含有MethodReplace注解的方法->hook替换。

    核心的hook替换是调用C++实现的:


    Dalvik虚拟机:


    Art虚拟机:


    Art虚拟的原理与Dalvik不一样,Art主要是改动“ArtMethod”的属性,让虚拟机“误觉得”改动后的方法即是原来的方法。以5.0为例:


    优势与亮点

    1.      提炼精华,简洁。轻便。适配广。完美的支持了Android 2.3到6.0系统,以及x86框架,机型覆盖率广。提供依据两个apk生成patch的工具。因而使用者仅仅需正向编程。通过工具生成patch文件。下发给client就可以,编程效率高。是完好的、高可用的热修复方案。

    2.      与业界其它方案对照:QQ空间、大众点评等採用的是动态载入dex方式。

    “后者纯java实现。但须要hack类的优化流程。将打CLASS_ISPREVERIFIED标签的类,去除此标签。以解决类与类引用不在一个dex中的异常问题。这会放弃dex optimize对启动执行速度的优化。原则上,这对于方法数没有大到须要multidex的应用,损失更明显。而前者不触犯原有的优化流程,仅仅点杀须要hook的方法,更为纯粹、有效。

    不足与缺陷

    1.      只支持android 方法的替换,不支持资源文件、xml的修复

    2.      慎用android:onClick="showToast"形式的事件注冊。

    3.      有人反应和“EventBus”不兼容。

    (自己測试良好)

    4.      有人反应fix之后部分手机出现ANR。(自己遇见过)

    集成注意事项

    1.      两手准备:一旦发现问题。1)server下发补丁包。2)server上把有问题的包替换成最新包

    2.      注意避免本地多次拉取补丁包。假设x版本号存在y补丁。则不再下载该补丁。

    资料链接

    1)  google的NDK样例

    https://github.com/googlesamples/android-ndk

    2)  几个开源热修复或插件化解决方式(排名不分先后)

    https://github.com/lzyzsd/AndroidHotFixExamples

    https://github.com/simpleton/dalvik_patch

    https://github.com/dodola/HotFix

    https://github.com/jasonross/Nuwa

    https://github.com/alibaba/AndFix

    https://github.com/rovo89/Xposed

    https://github.com/alibaba/dexposed

    https://github.com/bunnyblue/DroidFix

    https://github.com/CtripMobile/DynamicAPK

    3)  技术原理博客(排名不分先后)

    http://bugly.qq.com/blog/?

    p=781(QQ空间的解决方式)

    https://m.oschina.net/blog/308583(Android Dex分包方案)

    http://lirenlong.github.io/hotfix/(浅析xposed、dexposed和AndFix的原理)

    http://blog.csdn.net/lmj623565791/article/details/49883661(鸿洋)

    http://blog.csdn.net/vipzjyno1/article/details/21039349/(android反编译)
    最后,该篇文章所讲的内容我已经以demo的形式放在了github上,须要的朋友请看这里

  • 相关阅读:
    lighting
    移动端
    SVN常见问题
    前四章知识点小结
    如何不运用第三方变量实现两个数的交换
    awk
    sort
    cut
    sed
    30道Linux面试题
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7054999.html
Copyright © 2011-2022 走看看