Alibaba-AndFix Bug热修复框架原理及源码解析

YOLO26算法车道线检测+训练好的模型+360张数据集+pyqt可视化界面.zip 附训练好的 YOLO 权重与 PyQt 可视化检测界面,页面底部含可视化效果预览,毕设/课设开箱即用。 【数据集概况】 · 检测类别(中文):[未获取()] 【训练曲线与评估图】 【模型训练配置】 参数 | 值 模型 | yolo26n 训练轮数 | 100 epochs 输入尺寸 | 640x640 批次大小 | 24 优化器 | auto 初始学习率 | 0.01 训练设备 【关键指标汇总】 训练了 55 个 epoch,最终轮指标: 指标 | 数值 mAP50 | **0.9512** mAP50-95 | 0.6746 Precision | 0.8796 Recall | 0.8825 train/box_loss | 0.8608 train/cls_loss | 0.7232 val/box_loss | 0.9955 val/cls_loss | 0.5511 【训练过程分析】 这轮训练我经历了从初始到稳定的曲折过程。前 20 个epoch,loss 曲线呈现了陡峭的下降趋势,mAP50 指标从 0.8 开始逐步攀升,仿佛在寻找一个合适的平衡点。然而,从第 21 个epoch 开始,mAP50 的提升速率显著放缓,整体曲线显得有些曲折,有时甚至停滞不前,让我一度以为训练出现了问题。直到第 35 个epoch,loss 开始逐渐趋于平稳,这标志着模型已经找到了一个较好的收敛区间。到了最后的 20 个 epoch,尽管 mAP50 依旧在稳步上升,但提升幅度已经不大,这意味着模型已经接近其性能天花板。 在这个过程中,我重点关注了 box_loss 和 cls_loss 的变化。初期阶段,box_loss 快速下降,从 0.9 逐渐降至 0.86,而 cls_loss 则从 0.75 逐步下降至... 使用场景:毕业设计、课程设计、深度学习入门、工业场景落地验证。 立即下载

小憩之后,继续为你解读AndFix热修复框架,呵呵。

上一篇Alibaba-AndFix Bug热修复框架的使用已经介绍了AndFix的使用,这篇主要介绍AndFix原理以及源码解析。

AndFix原理

AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法。 
这里写图片描述

注:在Native层使用指针替换的方式替换bug方法,已达到修复bug的目的。

使用AndFix修复热修复的整体流程:

这里写图片描述

方法替换过程:

这里写图片描述

源码解析

解析源码从使用的方法一一解析。

在自定义Application中初始化PatchManger:

<code class="hljs fix has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">PatchManager mPatchManager </span>=<span class="hljs-string" style="color:#0880;box-sizing: border-box;"> new PatchManager();</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

直接实例化了一个PatchManger实例对象,接下看PatchManager类源码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">PatchManager</span>(Context context) {
        mContext = context;
        mAndFixManager = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> AndFixManager(mContext);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化AndFixManager</span>
        mPatchDir = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> File(mContext.getFilesDir(), DIR);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化存放patch补丁文件的文件夹</span>
        mPatchs = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> ConcurrentSkipListSet<Patch>();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化存在Patch类的集合,此类适合大并发</span>
        mLoaders = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> ConcurrentHashMap<String, ClassLoader>();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化存放类对应的类加载器集合</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

然后看AndFixManager的初始化:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">AndFixManager</span>(Context context) {
        mContext = context;
        mSupport = Compat.isSupport();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//判断Android机型是否适支持AndFix</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (mSupport) {
            mSecurityChecker = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> SecurityChecker(mContext);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化签名判断类</span>
            mOptDir = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> File(mContext.getFilesDir(), DIR);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化patch文件存放的文件夹</span>
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!mOptDir.exists() && !mOptDir.mkdirs()) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// make directory fail</span>
                mSupport = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
                Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"opt dir create error."</span>);
            } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!mOptDir.isDirectory()) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// not directory</span>
                mOptDir.delete();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//如果不是文件目录就删除</span>
                mSupport = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
            }
        }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isSupport</span>() {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//此处加了同步锁机制</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (isChecked)
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> isSupport;

        isChecked = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;
        <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// not support alibaba's YunOs</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> isYunOs = isYunOS();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//判断系统是否是YunOs系统,YunOs系统是阿里巴巴的系统</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> setup  =AndFix.setup();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//判断是Dalvik还是Art虚拟机,来注册Native方法</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> isSupportSDKVersion = isSupportSDKVersion();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//根据sdk版本判断是否支持</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!isYunOs && setup && isSupportSDKVersion) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//根据上面三个boolean值判断是否支持</span>
            isSupport = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;
        }

        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (inBlackList()) {
            isSupport = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
        }
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> isSupport;
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isSupportSDKVersion</span>() {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (android.os.Build.VERSION.SDK_INT >= <span class="hljs-number" style="color:#06666;box-sizing: border-box;">8</span>
                && android.os.Build.VERSION.SDK_INT <= <span class="hljs-number" style="color:#06666;box-sizing: border-box;">23</span>) {
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;
        }
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">setup</span>() {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">final</span> String vmVersion = System.getProperty(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"java.vm.version"</span>);
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> isArt = vmVersion != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span> && vmVersion.startsWith(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"2"</span>);
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> apilevel = Build.VERSION.SDK_INT;
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> setup(isArt, apilevel);
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (Exception e) {
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"setup"</span>, e);
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
        }
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//签名机制的初始化过程</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">SecurityChecker</span>(Context context) {
        mContext = context;
        init(mContext);
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//主要是获取当前应用的签名及其他信息,为了判断与patch文件的签名是否一致</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(Context context) {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
            PackageManager pm = context.getPackageManager();
            String packageName = context.getPackageName();

            PackageInfo packageInfo = pm.getPackageInfo(packageName,
                    PackageManager.GET_SIGNATURES);
            CertificateFactory certFactory = CertificateFactory
                    .getInstance(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"X.509"</span>);
            ByteArrayInputStream stream = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> ByteArrayInputStream(
                    packageInfo.signatures[<span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>].toByteArray());
            X509Certificate cert = (X509Certificate) certFactory
                    .generateCertificate(stream);
            mDebuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
            mPublicKey = cert.getPublicKey();
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (NameNotFoundException e) {
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"init"</span>, e);
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (CertificateException e) {
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"init"</span>, e);
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li></ul>

接下,看一下版本的初始化:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mPatchManager<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">.init</span>(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"version"</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

init方法源码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(String appVersion) {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!mPatchDir.exists() && !mPatchDir.mkdirs()) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// make directory fail</span>
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"patch dir create error."</span>);
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!mPatchDir.isDirectory()) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// not directory</span>
            mPatchDir.delete();
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
        }
        SharedPreferences sp = mContext.getSharedPreferences(SP_NAME,
                Context.MODE_PRIVATE);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//存储关于patch文件的信息</span>
        <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//根据你传入的版本号和之前的对比,做不同的处理</span>
        String ver = sp.getString(SP_VERSION, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>);
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (ver == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span> || !ver.equalsIgnoreCase(appVersion)) {
            cleanPatch();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//删除本地patch文件</span>
            sp.edit().putString(SP_VERSION, appVersion).commit();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//并把传入的版本号保存</span>
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {
            initPatchs();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化patch列表,把本地的patch文件加载到内存</span>
    }
}

<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">cleanPatch</span>() {
        File[] files = mPatchDir.listFiles();
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">for</span> (File file : files) {
            mAndFixManager.removeOptFile(file);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//删除所有的本地缓存patch文件</span>
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!FileUtil.deleteFile(file)) {
                Log.e(TAG, file.getName() + <span class="hljs-string" style="color:#0880;box-sizing: border-box;">" delete error."</span>);
        }
    }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">initPatchs</span>() {
        File[] files = mPatchDir.listFiles();
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">for</span> (File file : files) {
            addPatch(file);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//加载Patch文件</span>
        }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> Patch <span class="hljs-title" style="box-sizing: border-box;">addPatch</span>(File file) {
        Patch patch = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>;
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (file.getName().endsWith(SUFFIX)) {
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
                patch = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> Patch(file);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//实例化Patch对象</span>
                mPatchs.add(patch);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把patch实例存储到内存的集合中,在PatchManager实例化集合</span>
            } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (IOException e) {
                Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"addPatch"</span>, e);
            }
        }
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> patch;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li></ul>
Patch文件的加载
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">Patch</span>(File file) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throws</span> IOException {
        mFile = file;
        init();
}

<span class="hljs-annotation" style="color:#9b859d;box-sizing: border-box;">@SuppressWarnings</span>(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"deprecation"</span>)
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>() <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throws</span> IOException {
        JarFile jarFile = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>;
        InputStream inputStream = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>;
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
            jarFile = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> JarFile(mFile);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//使用JarFile读取Patch文件</span>
            JarEntry entry = jarFile.getJarEntry(ENTRY_NAME);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取META-INF/PATCH.MF文件</span>
            inputStream = jarFile.getInputStream(entry);
            Manifest manifest = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> Manifest(inputStream);
            Attributes main = manifest.getMainAttributes();
            mName = main.getValue(PATCH_NAME);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取PATCH.MF属性Patch-Name</span>
            mTime = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> Date(main.getValue(CREATED_TIME));<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取PATCH.MF属性Created-Time</span>

            mClassesMap = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> HashMap<String, List<String>>();
            Attributes.Name attrName;
            String name;
            List<String> strings;
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">for</span> (Iterator<?> it = main.keySet().iterator(); it.hasNext();) {
                attrName = (Attributes.Name) it.next();
                name = attrName.toString();
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//判断name的后缀是否是-Classes,并把name对应的值加入到集合中,对应的值就是class类名的列表</span>
                <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (name.endsWith(CLASSES)) {
                    strings = Arrays.asList(main.getValue(attrName).split(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">","</span>));
                    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (name.equalsIgnoreCase(PATCH_CLASSES)) {
                        mClassesMap.put(mName, strings);
                    } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {
                        mClassesMap.put(
                                name.trim().substring(<span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>, name.length() - <span class="hljs-number" style="color:#06666;box-sizing: border-box;">8</span>),<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// remove</span>
                                                                            <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// "-Classes"</span>
                                strings);
                    }
                }
            }
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">finally</span> {
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (jarFile != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {
                jarFile.close();
            }
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (inputStream != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {
                inputStream.close();
            }
        }

}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li></ul>

loadPatch方法源码

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mPatchManager<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">.loadPatch</span>()<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

loadPatch源码:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span> loadPatch() {
        mLoaders<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>put(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"*"</span>, mContext<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>getClassLoader());<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// wildcard</span>
        <span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">Set</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><</span><span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">String</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">></span> patchNames;
        <span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">List</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><</span><span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">String</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">></span> classes;
        for (Patch patch : mPatchs) {
            patchNames <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> patch<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>getPatchNames();
            for (<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">String</span> patchName : patchNames) {
                classes <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> patch<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>getClasses(patchName);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取patch对用的class类的集合List</span>
                mAndFixManager<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>fix(patch<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>getFile(), mContext<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>getClassLoader(),
                        classes);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//修复bug方法</span>
            }
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
fix bug
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">fix</span>(File file, ClassLoader classLoader,
            List<String> classes) {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!mSupport) {
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
        }
        <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//判断patch文件的签名</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!mSecurityChecker.verifyApk(file)) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// security check fail</span>
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
        }

        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
            File optfile = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> File(mOptDir, file.getName());
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> saveFingerprint = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (optfile.exists()) {
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// need to verify fingerprint when the optimize file exist,</span>
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// prevent someone attack on jailbreak device with</span>
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Vulnerability-Parasyte.</span>
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// btw:exaggerated android Vulnerability-Parasyte</span>
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// http://secauo.com/Exaggerated-Android-Vulnerability-Parasyte.html</span>
                <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (mSecurityChecker.verifyOpt(optfile)) {
                    saveFingerprint = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
                } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!optfile.delete()) {
                    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
                }
            }
            <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//加载patch文件中的dex</span>
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">final</span> DexFile dexFile = DexFile.loadDex(file.getAbsolutePath(),
                    optfile.getAbsolutePath(), Context.MODE_PRIVATE);

            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (saveFingerprint) {
                mSecurityChecker.saveOptSig(optfile);
            }

            ClassLoader patchClassLoader = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> ClassLoader(classLoader) {
                <span class="hljs-annotation" style="color:#9b859d;box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">protected</span> Class<?> <span class="hljs-title" style="box-sizing: border-box;">findClass</span>(String className)
                        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throws</span> ClassNotFoundException {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//重写ClasLoader的findClass方法</span>
                    Class<?> clazz = dexFile.loadClass(className, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">this</span>);
                    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (clazz == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>
                            && className.startsWith(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"com.alipay.euler.andfix"</span>)) {
                        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> Class.forName(className);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// annotation’s class</span>
                                                        <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// not found</span>
                    }
                    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (clazz == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {
                        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> ClassNotFoundException(className);
                    }
                    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> clazz;
                }
            };
            Enumeration<String> entrys = dexFile.entries();
            Class<?> clazz = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>;
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">while</span> (entrys.hasMoreElements()) {
                String entry = entrys.nextElement();
                <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classes != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span> && !classes.contains(entry)) {
                    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">continue</span>;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// skip, not need fix</span>
                }
                clazz = dexFile.loadClass(entry, patchClassLoader);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取有bug的类文件</span>
                <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (clazz != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {
                    fixClass(clazz, classLoader);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// next code</span>
                }
            }
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (IOException e) {
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"pacth"</span>, e);
    }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">fixClass</span>(Class<?> clazz, ClassLoader classLoader) {
        Method[] methods = clazz.getDeclaredMethods();
        MethodReplace methodReplace;
        String clz;
        String meth;
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">for</span> (Method method : methods) {
            <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取此方法的注解,因为有bug的方法在生成的patch的类中的方法都是有注解的,下面会给图进行展示</span>
            methodReplace = method.getAnnotation(MethodReplace.class);
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (methodReplace == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>)
                <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">continue</span>;
            clz = methodReplace.clazz();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取注解中clazz的值</span>
            meth = methodReplace.method();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//获取注解中method的值</span>
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!isEmpty(clz) && !isEmpty(meth)) {
                replaceMethod(classLoader, clz, meth, method);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//next code</span>
            }
    }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">replaceMethod</span>(ClassLoader classLoader, String clz,
            String meth, Method method) {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
            String key = clz + <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"@"</span> + classLoader.toString();
            Class<?> clazz = mFixedClass.get(key);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//判断此类是否被fix</span>
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (clazz == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// class not load</span>
                Class<?> clzz = classLoader.loadClass(clz);
                <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// initialize target class</span>
                clazz = AndFix.initTargetClass(clzz);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//初始化class</span>
            }
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (clazz != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// initialize class OK</span>
                mFixedClass.put(key, clazz);
                Method src = clazz.getDeclaredMethod(meth,
                        method.getParameterTypes());<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//根据反射获取到有bug的类的方法(有bug的apk)</span>
                AndFix.addReplaceMethod(src, method);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//src是有bug的方法,method是补丁方法</span>
            }
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (Exception e) {
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"replaceMethod"</span>, e);
    }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">addReplaceMethod</span>(Method src, Method dest) {
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {
            replaceMethod(src, dest);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//调用了native方法,next code</span>
            initFields(dest.getDeclaringClass());
        } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (Throwable e) {
            Log.e(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"addReplaceMethod"</span>, e);
        }
}
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">native</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">replaceMethod</span>(Method dest, Method src);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li></ul>

由于Android4.4后才用的Art虚拟机,之前的系统都是Dalvik虚拟机,因此Natice层写了2个方法,对不同的系统做不同的处理方式。

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">extern</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> dalvik_replaceMethod(JNIEnv* env, jobject src, jobject dest);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//Dalvik</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">extern</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> art_replaceMethod(JNIEnv* env, jobject src, jobject dest);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//Art</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
Dalvik replaceMethod的实现:
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">extern <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span> __attribute__ ((visibility (<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"hidden"</span>))) dalvik_replaceMethod(
        JNIEnv<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> env, jobject src, jobject dest) {
    jobject clazz <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> env<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>CallObjectMethod(dest, jClassMethod);
    ClassObject<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> clz <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> (ClassObject<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>) dvmDecodeIndirectRef_fnPtr(
            dvmThreadSelf_fnPtr(), clazz);
    clz<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>status <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> CLASS_INITIALIZED;

    Method<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> meth <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> (Method<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>) env<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>FromReflectedMethod(src);
    Method<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> target <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> (Method<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>) env<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>FromReflectedMethod(dest);
    LOGD(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dalvikMethod: %s"</span>, meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>name);

    meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>jniArgInfo <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0x80000000</span>;
    meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>accessFlags <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">|=</span> ACC_NATIVE;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把Method的属性设置成Native方法</span>

    int argsSize <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dvmComputeMethodArgsSize_fnPtr(meth);
    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">!</span>dvmIsStaticMethod(meth))
        argsSize<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">++</span>;
    meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>registersSize <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>insSize <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> argsSize;
    meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>insns <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> (<span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>) target;

    meth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>nativeFunc <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dalvik_dispatcher;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把方法的实现替换成native方法</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>
Art replaceMethod的实现:
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//不同的art系统版本不同处理也不同</span>
extern <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span> __attribute__ ((visibility (<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"hidden"</span>))) art_replaceMethod(
        JNIEnv<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> env, jobject src, jobject dest) {
    <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (apilevel <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">></span> <span class="hljs-number" style="color:#06666;box-sizing: border-box;">22</span>) {
        replace_6_0(env, src, dest);
    } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (apilevel <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">></span> <span class="hljs-number" style="color:#06666;box-sizing: border-box;">21</span>) {
        replace_5_1(env, src, dest);
    } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {
        replace_5_0(env, src, dest);
    }
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//以5.0为例:</span>
<span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span> replace_5_0(JNIEnv<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> env, jobject src, jobject dest) {
    art<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::mirror</span><span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::ArtMethod</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> smeth <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span>
            (art<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::mirror</span><span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::ArtMethod</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>) env<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>FromReflectedMethod(src);

    art<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::mirror</span><span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::ArtMethod</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> dmeth <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span>
            (art<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::mirror</span><span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::ArtMethod</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>) env<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>FromReflectedMethod(dest);

    dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>class_loader_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span>
            smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>class_loader_; <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//for plugin classloader</span>
    dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>clinit_thread_id_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span>
            smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>clinit_thread_id_;
    dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>status_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> (<span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span> <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span>)((int)smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>status_<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-</span><span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>);
    <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把一些参数的指针给补丁方法</span>
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>declaring_class_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>access_flags_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>access_flags_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>frame_size_in_bytes_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>frame_size_in_bytes_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>dex_cache_initialized_static_storage_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span>
            dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>dex_cache_initialized_static_storage_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>dex_cache_resolved_types_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>dex_cache_resolved_types_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>dex_cache_resolved_methods_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>dex_cache_resolved_methods_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>vmap_table_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>vmap_table_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>core_spill_mask_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>core_spill_mask_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>fp_spill_mask_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>fp_spill_mask_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>mapping_table_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>mapping_table_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>code_item_offset_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>code_item_offset_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>entry_point_from_compiled_code_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span>
            dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>entry_point_from_compiled_code_;

    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>entry_point_from_interpreter_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>entry_point_from_interpreter_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>native_method_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>native_method_;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把补丁方法替换掉</span>
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>method_index_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>method_index_;
    smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>method_dex_index_ <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>method_dex_index_;

    LOGD(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"replace_5_0: %d , %d"</span>, smeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>entry_point_from_compiled_code_,
            dmeth<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>entry_point_from_compiled_code_);

}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li></ul>

添加Patch

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mPatchManager<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">.addPatch</span>(path)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

源码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">addPatch</span>(String path) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throws</span> IOException {
        File src = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> File(path);
        File dest = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> File(mPatchDir, src.getName());
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!src.exists()) {
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> FileNotFoundException(path);
        }
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (dest.exists()) {
            Log.d(TAG, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"patch ["</span> + path + <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"] has be loaded."</span>);
            <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
        }
        FileUtil.copyFile(src, dest);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// copy to patch's directory</span>
        Patch patch = addPatch(dest);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//同loadPatch中的addPatch一样的操作</span>
        <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (patch != <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {
            loadPatch(patch);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//加载pach,同上loadPatch</span>
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

移除Patch

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mPatchManager<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">.removeAllPatch</span>()<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

源码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">removeAllPatch</span>() {
        cleanPatch();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//删除本地缓存的patch文件列表</span>
        SharedPreferences sp = mContext.getSharedPreferences(SP_NAME,
                Context.MODE_PRIVATE);
        sp.edit().clear().commit();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把关于patch的数据进行清空</span>
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

到此源代码就解析结束。

反编译Patch dex文件代码

patch文件中.dex文件反编译后,看到源码效果如下: 
这里写图片描述 
红框标注的部分,就是补丁方法。方法的注解部分写了clazz和method的值,对应着apk包中的类名和方法名称。


原文地址: http://blog.youkuaiyun.com/qxs965266509/article/details/49816007

IEC 61851-23:2023 电动汽车导电充电系统 - 第23部分:直流电动汽车供电设备 - 完整英文电子版(388页) IEC 61851-23:2023适用于用于在供电网络与电动汽车(EV)之间实现能量传输的电动车供电设备,A侧额定最大电压可达1000伏交流电或最高1500伏直流电,B侧额定最大电压最高可达1500伏直流电。 本文件规定了系统A、系统B和系统C的电动车供应设备,定义见附件AA、附件BB和附件CC。 立即下载

相关推荐

phone-harness/mcp 把手机接进AI(源码附安装部署教程)

phone-harness/mcp 做的不是模拟器玩具,而是把真实手机操作能力接成一个标准 MCP 服务:给 Claude、Cursor、ChatGPT、Codex、VS Code 等客户端填一个 URL,完成 OAuth 登录后,AI 就能直接看屏幕、点按、输入、滑动、启动 App,甚至连真机 iPhone 和云端 Android 模拟器都能统一调度。 它的价值在于把过去依赖 Mac、adb、配对线缆和本地环境的移动端自动化,压缩成“一个地址+一次登录”的接入成本,特别适合需要让智能体真正落到手机场景里的测试、演示和流程执行。 项目把能力拆成一组很实用的工具:列设备、启停设备、截图、识别屏幕文字、坐标点击、长按、滑动、输入、按键、查前台应用、启动应用,基本覆盖了手机远程操控的主路径。 收费方式也写得很直白:云端 Android 按分钟计费,iPhone 是包月订阅,临时会话和保存状态的设备也区分清楚,减少了“能不能跑、怎么计费、数据会不会丢”这类实际使用时最常见的疑问。 更重要的是,它没有试图重新发明一套生态,而是紧贴 MCP,把“让 AI 真正碰到手机”这件事做成可插拔基础设施。

Alibaba-AndFix Bug热修复框架的使用

AndFix是一个Android App的在线热补丁框架。使用此框架,我们能够在不重复发版的情况下,在线修改App中的Bug。AndFix就是 “Android Hot-Fix”的缩写。 就目前来说,AndFix支持Android 2.3到6.0版本,并且支持arm 与 X86系统架构的设备。完美支持Dalvik与ART的Runtime。 AndFix 的补丁文件是以 .apatch 结尾的文件。 AndFix是阿里巴巴开源项目。

恰好你来,恰好我在 567

关于AI开发方法论-以文档为索引的高质量协作开发:让一次现象描述精准命中几个代码块

对AI的编码规范进行约束

AndFix原理以及源码解析

小憩之后,继续为你解读AndFix热修复框架,呵呵。 上一篇Alibaba-AndFix Bug热修复框架的使用已经介绍了AndFix的使用,这篇主要介绍AndFix原理以及源码解析。 AndFix原理源码解析 在自定义Application中初始化PatchMangerinit方法源码 Patch文件的加载 loadPatch方法源码 fix bugD

amyli的专栏 840

数字雕刻基于CatmulI-Clark细分与笔刷位移场的ZBrush流程建模:月哨兵角色精细度上限分析

内容概要:本文以“月哨兵”科幻角色数字雕刻工程为实例,系统构建了从程序化粗模到高精度雕刻的完整数学模型。研究涵盖重拓扑、Catmul-Clark细分、笔刷位移场建模、多部件组装及精细度上限分析等核心环节。通过ZRemesher将304,050顶点粗模重拓扑为28,600顶点的全四边形网格,并逐级细分至732万面,实测面数递推F(k)=F₀·4ᵏ完全符合理论。利用ZBrush Python接口注入Standard笔刷操作,首次通过同拓扑OBJ逐顶点差分获得真实位移场数据,实测最大位移0.454873,8.756%顶点发生显著位移。提出“理论-内存-拓扑-视觉”四层精细度上限模型,指出在24GB内存条件下工程合理上限为10⁷~10⁸面,视觉收益受渲染分辨率制约趋于饱和。最终完成755万面的组装网格并经工程文件回读验证一致性。; 适合人群:具备三维建模与数字雕刻基础,熟悉ZBrush工作流,从事角色资产开发或程序化内容生成的技术美术、图形学研究人员及高阶数字艺术家。; 使用场景及目标:①理解Catmul-Clark细分曲面在工业级雕刻流程中的数学机制;②掌握基于脚本驱动的可复核雕刻工程构建方法;③评估高面数模型的内存代价与视觉收益平衡;④学习重拓扑、位移场量化、多部件合并等关键技术的工程实现。; 阅读建议:本文强调数学建模与实证闭环,建议结合附录中的脚本与数据文件进行复现实践,重点关注逐顶点差分、细分递推验证与四层上限模型的构建逻辑,以深入掌握高精度数字雕刻的系统性工程方法。

公司内网软件下载站,公司内网软件下载站

公司内网软件下载站,公司内网软件下载站

Alibaba-Dexposed Bug框架原理及源码解析

目录(?)[+] Alibaba的AndFix热修复:  Alibaba-AndFix Bug热修复框架的使用  Alibaba-AndFix Bug热修复框架原理及源码解析 上一篇中已经介绍了Alibaba-Dexposed框架在线热补丁修复的使用 ,这篇主要是了解框架的原理和源码解析。 原理: 在Dalvik虚拟机下,主要是通过改变一个方法对象方法在Dalvik虚拟

omnispace的博客 677

syslog_test.py

syslog_test.py

Android 热更新AndFix的分析

1.AndFix 只能修复方法级别的bug 使用流程:添加依赖→封装工具类→生成差异包(.patch文件)→loadpatch方法更新 源码: 初始化源码:PatchManager→init(比较版本号,删除旧版本) 加载源码:addpatch→initPatchs()→addpatch()→loadpatch()→fix()→fixclass()→replaceMethod()→ad...

长歌的博客 343

Simulink “双碳”背景下汽车减少碳排放建模与仿真

内容概要:本文围绕“双碳”战略背景,系统阐述了基于Simulink的汽车碳排放建模与仿真技术,重点引入模糊PID控制优化动力系统性能,以实现节能减排目标。文档整合了多个Matlab/Simulink科研仿真案例,涵盖无刷直流电机(BLDC)控制、三相PWM整流器、电池管理系统、路径规划、信号处理、智能优化算法及图像处理等领域,全面展示Matlab在智能控制与绿色能源系统中的应用价值。同时强调科研应兼具严谨逻辑、创新思维与工具赋能,并提供完整的仿真资源链接与学习路径支持实践落地。; 适合人群:具备Matlab/Simulink基础,从事自动化、电气工程、车辆工程、控制科学、电力电子及智能制造等相关领域的科研人员或高年级本科生、研究生;适用于开展节能减排、新能源系统优化、智能控制算法研究等课题的研究者。; 使用场景及目标:①学习在Simulink中构建汽车能耗与排放仿真模型并应用模糊PID进行动态优化;②掌握BLDC、PWM整流器等关键部件的建模与控制策略设计;③借鉴丰富案例提升科研效率,拓展在智能控制、路径规划、信号处理等方向的应用能力;④通过提供的网盘资源获取完整代码与资料,支撑论文写作与项目开发。; 阅读建议:建议按照资源目录顺序系统学习,结合百度网盘提供的Matlab/Simulink代码动手实践,重点关注控制策略的设计、仿真结果的分析与优化过程,同时注重培养科研思维与工程实际问题的结合能力。

西部牛仔_1794033330851.apk

西部牛仔_1794033330851.apk

android Alibaba热补丁修复使用

原文地址:http://blog.youkuaiyun.com/qxs965266509/article/details/49821413

super黑兔的博客 1217

状态估计变分贝叶斯近似的递归噪声自适应卡尔曼滤波(Matlab代码实现)

内容概要:本文详细介绍了一种基于变分贝叶斯近似的递归噪声自适应卡尔曼滤波方法,并配套提供了完整的Matlab代码实现。该方法旨在解决传统卡尔曼滤波在面对过程噪声和观测噪声统计特性未知或时变情况下性能退化的问题,通过引入变分贝叶斯推断技术,实现对噪声协方差的在线联合估计与动态更新,从而提升滤波器在非平稳环境中的状态估计精度与鲁棒性。文中系统阐述了算法的理论基础、数学推导流程、递归计算结构及关键实现步骤,涵盖了概率图模型构建、似然函数近似、变分迭代优化等核心技术环节,适用于复杂动态系统中的自适应信号处理与状态估计任务。; 适合人群:具备良好线性系统理论、概率统计与贝叶斯估计基础,并熟悉Matlab编程的研究生、科研人员及从事导航、控制、传感融合等相关领域的工程技术人员; 使用场景及目标:①应对实际工程中因噪声先验信息缺失或环境变化导致的标准卡尔曼滤波失效问题;②应用于无人机导航、智能驾驶、工业状态监测、传感器融合等高精度自适应估计场景,提升系统在不确定环境下的稳定性和准确性; 阅读建议:建议读者结合所提供的Matlab代码逐模块研读,重点理解变分贝叶斯迭代过程中噪声协方差矩阵的后验更新机制,并通过仿真实验对比所提方法与标准KF/EKF/UKF的估计性能差异,深入掌握噪声自适应滤波的设计思想与实现技巧。

PUMA:DOA估计模式的改进实现(Matlab代码实现)

内容概要:本文围绕PUMA(Propagator Method-based DOA Estimation)算法在波达方向(DOA)估计中的改进实现展开,重点在于通过Matlab编程对算法进行仿真与性能验证。作为阵列信号处理领域的高分辨率DOA估计算法,PUMA在传统方法基础上提升了估计精度与鲁棒性,尤其在低信噪比、小样本等恶劣条件下仍能保持优异性能。文中系统阐述了PUMA算法的理论基础、数学模型及其相较于MUSIC、ESPRIT等经典算法的优势,并通过仿真实验进行对比分析,展示其在分辨力、稳定性和计算效率方面的综合优势,适用于实际雷达、无线通信与电子侦察等应用场景。; 适合人群:具备信号处理、通信工程、电子信息或雷达系统等相关专业背景的研究生、科研人员及工程技术人员,熟悉阵列信号处理理论与Matlab编程环境者尤佳; 使用场景及目标:①用于学术研究中DOA估计算法的性能优化与新方法对比验证;②应用于雷达系统、5G/6G通信、智能天线、电子对抗等领域的高精度空间谱估计任务;③作为Matlab仿真实践资源,支持课程设计、学位论文复现与科研项目开发; 阅读建议:建议结合阵列信号处理基础知识体系学习本资源,重点关注PUMA算法的改进机制与核心代码实现逻辑,建议动手运行并调整仿真参数以深入理解不同因素(如阵元数、信噪比、快拍数)对估计性能的影响。

Bybit面经

这段总结描述了求职者在Bybit面试过程中的经历和相关问题,包括面试内容、求职者向面试官提问的问题以及关于Bybit的信息

郑泽洲的博客 2578

环境科研人必备:手把手教你用EPISuite 4.1批量预测化合物毒性(附ECOSAR实战)

本文详细介绍了EPISuite 4.1在环境毒理学研究中的应用,重点解析了ECOSAR模块的化合物毒性预测技术。通过批量处理实战和科研案例,帮助环境科研人员快速评估化学物质对水生生态系统的风险,提升工作效率。文章还涵盖了EPISuite核心模块的功能分类及ECOSAR模型的技术原理与算法特点。

weixin_28738165的博客 539
上一篇: Alibaba-Dexposed框架在线热补丁修复的使用
下一篇: Alibaba-AndFix Bug热修复框架的使用
Omni-Space
博客等级 码龄11年 2158粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值