精华内容
下载资源
问答
  • hotfix

    2017-03-13 09:49:10
    tinker在加固包生成补丁时,生成的补丁太大,所有改用hotfix方案 1.方案比较: 平台 阿里百川HotFix AndFix Tinker Qzone Robust 即时生效 yes yes no no yes 性能损耗 较小 较小 较大 ...

    tinker在加固包生成补丁时,生成的补丁太大,所有改用hotfix方案

    1.方案比较:

    平台 阿里百川HotFix AndFix Tinker Qzone Robust
    即时生效 yes yes no no yes
    性能损耗 较小 较小 较大 较大 较小
    侵入式打包 无侵入式打包 无侵入式打包 依赖侵入式打包 依赖侵入式打包 依赖侵入式打包
    Rom体积 较小 较小 较大 较小 较小
    接入复杂度 傻瓜式接入 比较简单 复杂 比较简单 复杂
    补丁包大小 较小 较小 较小 较大 一般
    全平台支持 yes yes yes yes yes
    类替换 yes(即将支持) yes yes yes no
    so替换 yes(即将支持) no yes no no
    资源替换 yes(即将支持) no yes yes no

    HotFix总体来说最大的优势在于:

    • 补丁即时生效,不需要应用重启;
    • 补丁包同样采用差量技术,生成的PATCH体积小;
    • 对应用无侵入,几乎无性能损耗;
    • 傻瓜式接入。

    但是HotFix1.0版本也有美中不足, 比如暂时不支持新增类和资源,so文件的修复等(这些限制均会在一月中的2.0版本全部去掉),但是作为一项定位为线上紧急BUG的热修复的服务来说,能够真正做到BUG即时修复用户无感知,同时保证对应用性能不产生不必要的损耗,在热修复方面不失为一个好的选择。

    2.接入文档:

    http://baichuan.taobao.com/docs/doc.htm?spm=a3c0d.7629140.0.0.3Y2Pix&treeId=234&articleId=105457&docType=1


    3.管理平台:

    https://hotfix.taobao.com/


    4.注意事项

    1.暂时不支持android7

    2.多个补丁同时下发,只会下载最新的补丁

    3.如果生成补丁的基础版本和当前安装的app版本不一致,补丁中功能的改变不牵涉到新增(新增方法,成员,类)的部分,也可以正常打上,如果牵涉到新增,打不上,但是不会crash,打不上必须清掉这个patch,不然每次都会尝试一次

    4.加固包补丁用加固前的基础包比较生成






    展开全文
  • Hotfix

    2020-11-26 13:17:03
    <div><p>该提问来源于开源项目:LLK/scratch-www</p></div>
  • Hotfix 2.4.1

    2020-12-28 11:21:06
    <div><p>Issue tracker for hotfix version 2.4.1</p><p>该提问来源于开源项目:valendesigns/option-tree</p></div>
  • Hotfix merge

    2020-12-01 18:14:13
    <p>hotfix-7.10.x -> hotfix. <h2>Types of changes <ul><li>[X] Bug fix (non-breaking change which fixes an issue)</li><li>[ ] New feature (non-breaking change which adds functionality)</li><li>[ ] ...
  • Hotfix 0.7.0

    2020-11-27 18:47:36
    This hotfix makes sure the trigger get paused before the on_trigger hook get called. <p>Also we don't need to write the microphone level to a file, this has got no use for us. </p><p>该提问来源于...
  • Evolution hotfix

    2021-01-12 01:52:52
    <div><p>Tiny evolution hotfix. https://github.com/CleverRaven/Cataclysm-DDA/pull/28797</p> <h4>Summary <p>SUMMARY: Balance "Evolution hotfix" <ul><li>Slowed down hunter evolution and its ...
  • Hotfix fixes

    2020-12-01 18:10:17
    <p>Code refactoring on hotfix branch <h2>Motivation and Context <h2>How To Test This <h2>Types of changes <ul><li>[x] Bug fix (non-breaking change which fixes an issue)</li><li>[ ] New feature ...
  • 0.3.1 Hotfix

    2020-12-01 16:27:52
    Add change log for 0.3.1<a href="https://github.com/Microsoft/java-debug/pull/107">#107</a> - </li><li>[x] 11/17 - Signed RC Bits(<a href="https://vscjavaci.cloudapp.net/job/vscode-java-debug-hotfix/...
  • Hotfix 116

    2020-12-02 18:17:35
    <div><p>This is an hotfix for #116 found on several websites. It load a very small <code>index.html</code> and then redirect to <code>main.html</code> which is the real app.</p> <p>I didn't build ...
  • <div><p>Fixed <code>ChangeAction</code> so it rejects change JSON files that have change types other than <code>none</code> or <code>hotfix</code>. This will prevent accidental publishing of bad ...
  • HotFix_FrameWork-源码

    2021-03-10 17:09:01
    HotFix_FrameWork
  • 4.1.27-hotfix

    2019-01-20 15:54:43
    4.1.27-hotfix
  • Remove Hotfix Branches

    2020-12-01 16:42:44
    <p>If a re-user is using a hotfix branch they should redeploy from the matching tagged release. Something like: <pre><code> diff - branch: origin/hotfix/0.19.0.3 + branch: refs/tags/0.19.0.3 ...
  • Hotfix Version 2.2.1

    2020-12-29 02:56:19
    <div><p>Creating a hotfix issue for the current 2.2.x branch. If you find bugs that need to be addressed immediately please discuss them here. <p>This hotfix version should be released by the end of ...
  • remove hotfix feature

    2020-11-27 20:05:12
    hotfix" (include any commit that starts with "HOTFIX") <p>I never saw this being used, so I'd opt to delete that feature to avoid all these github lookups on deploy and when displaying...
  • Hotfix/pyyaml

    2020-12-01 14:26:49
    <div><p>Hotfix pour PyYAML</p><p>该提问来源于开源项目:zestedesavoir/zds-site</p></div>
  • Android HotFix

    2016-11-30 16:23:00
    What is HotFix?以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装(来自:安卓App热补丁动态修复技术介绍) HotFix原理 首先HotFix原理是基于Android Dex分包方案的,而Dex分包...

    What is HotFix?

    以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装(来自:安卓App热补丁动态修复技术介绍)
    HotFix原理
    首先HotFix原理是基于Android Dex分包方案的,而Dex分包方案的关键就是Android的ClassLoader体系。ClassLoader的继承关系如下:

    ClassLoader继承关系

    这里我们可以用的是PathClassLoader和DexClassLoader,接下来看看这两个类的注释:

    PatchClassLoader
    /**
    * Provides a simple {@link ClassLoader} implementation that operates on a list
    * of files and directories in the local file system, but does not attempt to
    * load classes from the network. Android uses this class for its system class
    * loader and for its application class loader(s).
    */

    这个类被用作系统类加载器和应用类(已安装的应用)加载器。

    DexClassLoader
    /**
    * A class loader that loads classes from {@code .jar} and {@code .apk} files
    * containing a {@code classes.dex} entry. This can be used to execute code not
    * installed as part of an application.
    */

    注释可以看出,这个类是可以用来从.jar文件和.apk文件中加载classed.dex,可以用来执行没有安装的程序代码。
    通过上面的两个注释可以清楚这两个类的作用了,很显然我们要用的是DexClassLoader,对插件化了解的小伙伴们对这个类肯定不会陌生的,对插件化不了解的也没关系。下面会更详细的介绍。
    我们知道了PathClassLoader和DexClassLoader的应用场景,接下来看一下是如何加载类的,看上面的继承关系这里两个类都是继承自BaseDexClassLoader,所以查找类的方法也在BaseDexClassLoader中,下面是部分源码:

    /**
     * Base class for common functionality between various dex-based
     * {@link ClassLoader} implementations.
     */
    public class BaseDexClassLoader extends ClassLoader {
    
         /** structured lists of path elements */
         private final DexPathList pathList;
    
         //...some code
    
         @Override
         protected Class<?> findClass(String name) throws ClassNotFoundException {
    
             Class clazz = pathList.findClass(name);
             if (clazz == null) {
                 throw new ClassNotFoundException(name);
             }
    
             return clazz;
    
         }
    
        //...some code
    }

    可以看到在findClass()方法中用到了pathList.findClass(name),而pathList的类型是DexPathList,下面看一下DexPathList的findClass()方法源码:

    /**
     * A pair of lists of entries, associated with a {@code ClassLoader}.
     * One of the lists is a dex/resource path — typically referred
     * to as a "class path"list, and the other names directories
     * containing native code libraries. Class path entries may be any of:
     * a {@code .jar} or {@code .zip} file containing an optional
     * top-level {@code classes.dex} file as well as arbitrary resources,
     * or a plain {@code .dex} file (with no possibility of associated
     * resources).
     *
     * <p>This class also contains methods to use these lists to look up
     * classes and resources.</p>
     */
    /*package*/ final class DexPathList {
    
         /** list of dex/resource (class path) elements */
         private final Element[] dexElements;
    
        /**
         * Finds the named class in one of the dex files pointed at by
         * this instance. This will find the one in the earliest listed
         * path element. If the class is found but has not yet been
         * defined, then this method will define it in the defining
         * context that this instance was constructed with.
         *
         * @return the named class or {@code null} if the class is not
         * found in any of the dex files
         */
         public Class findClass(String name) {
             for (Element element : dexElements) {
                 DexFile dex = element.dexFile;
                 if (dex != null) {
                     Class clazz = dex.loadClassBinaryName(name, definingContext);
                     if (clazz != null) {
                         return clazz;
                     }
                 }
             }
    
             return null;
    
         }
    }

    这个方法里面有调用了dex.loadClassBinaryName(name, definingContext),然后我们来看一下DexFile的这个方法:

    /**
     * Manipulates DEX files. The class is similar in principle to
     * {@link java.util.zip.ZipFile}. It is used primarily by class loaders.
     * <p>
     * Note we don't directly open and read the DEX file here. They're memory-mapped
     * read-only by the VM.
     */
    public final class DexFile {
    
        /**
         * See {@link #loadClass(String, ClassLoader)}.
         *
         * This takes a "binary" class name to better match ClassLoader semantics.
         *
         * @hide
         */
         public Class loadClassBinaryName(String name, ClassLoader loader){
    
             return defineClass(name, loader, mCookie);
    
         }
    
         private native static Class defineClass(String name, ClassLoader loader, int cookie);
    }

    好了,关联的代码全部贴上了,理解起来并不难,总结一下流程:BaseDexClassLoader中有一个DexPathList对象pathList,pathList中有个Element数组dexElements(Element是DexPathList的静态内部类,在Element中会保存DexFile的对象),然后遍历Element数组,通过DexFile对象去查找类。
    更通俗的说:

    一个ClassLoader可以包含多个dex文件,每个dex文件是一个Element,多个dex文件排列成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找类则返回,如果找不到从下一个dex文件继续查找。(出自安卓App热补丁动态修复技术介绍)
    so,通过上面介绍,我们可以将patch.jar(补丁包),放在dexElements数组的第一个元素,这样优先找到我们patch.jar中的新类去替换之前存在bug的类。
    方案有了,但是我们还差一个步骤,就是防止类被打上CLASS_ISPREVERIFIED的标记
    解释一下:在apk安装的时候,虚拟机会将dex优化成odex后才拿去执行。在这个过程中会对所有class一个校验。校验方式:假设A该类在它的static方法,private方法,构造函数,override方法中直接引用到B类。如果A类和B类在同一个dex中,那么A类就会被打上CLASS_ISPREVERIFIED标记。A类如果还引用了一个C类,而C类在其他dex中,那么A类并不会被打上标记。换句话说,只要在static方法,构造方法,private方法,override方法中直接引用了其他dex中的类,那么这个类就不会被打上CLASS_ISPREVERIFIED标记。(引用自Android热补丁动态修复技术(二):实战!CLASS_ISPREVERIFIED问题!)
    O..O..OK,现在很清楚了,实现热修复,我们需要完成两个任务:
    改变BaseDexClassLoader中的dexElements数组,将我们的patch.jar插入到dexElements数组的第一个位置。
    在打包的时候,我们要阻止类被打上CLASS_ISPREVERIFIED标记

    HotFix框架汇总
    RocooFix(推荐)
    Nuwa
    HotFix
    AndFix
    Tinker_imitator(微信热更新方案实践)

    RoccoFix使用问题
    RocooFix的正确教程,不生成patch.jar请按这个步骤来执行
    待更新

    参考
    安卓App热补丁动态修复技术介绍
    Android dex分包方案
    Android 热补丁动态修复框架小结
    Android热补丁动态修复技术(一):从Dex分包原理到热补丁
    Android热补丁动态修复技术(二):实战!CLASS_ISPREVERIFIED问题!
    Android热补丁动态修复技术(三)—— 使用Javassist注入字节码,完成热补丁框架雏形(可使用)
    Android热补丁动态修复技术(四):自动化生成补丁——解决混淆问题

    文/zyyoona7(简书作者)
    原文链接:http://www.jianshu.com/p/6f0ae1e364d9
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    展开全文
  • 2.1.2 Hotfix Testing

    2020-11-25 02:44:13
    <div><p>Can everyone please test the hotfix-es-50 branch?</p><p>该提问来源于开源项目:10up/ElasticPress</p></div>
  • Hotfix Email Reply

    2020-12-26 00:33:59
    <div><p><code>createTicketSession</code> does not exists, here is a hotfix for email replies. feel free to clean it up</p><p>该提问来源于开源项目:opensupports/opensupports</p></div>
  • introduce hotfix capability

    2021-01-01 12:53:17
    and I requested to update <code>update-from-repo.sh</code> with authentic updates also, it would be nice to have a general hotfix possiblility. <p>e.g. if we have a typo in a script which can be fixed...
  • New card hotfix

    2020-12-05 18:14:50
    <div><p>This hotfix addresses 3 issues - #1116 new cards during meeting - #1117 meeting summary cards bug - make cards read-only when they're in the archive (no issue for this one)</p><p>该提问...
  • I would still like to have a hotfix branch hotfix/1.X.1 but this logic creates hotfix/support/1.X.0/1.X.1 <p>I am hotfixing via CI server and need control over the name of the hotfix branch.</p><p>该...
  • Actuator group hotfix

    2021-01-10 03:16:00
    <div><p>, This is hotfix for actuator controls group "manual passthrough". Documentation (http://pixhawk.org/dev/mixing) says that it should be on group 3, but PX4IO supports only two groups ...
  • Color format hotfix

    2020-12-25 23:03:36
    t affect anything due to bug in gfx, but this hotfix should be replaced with appropriate off-screen render target (see #109) <p>The reason I pushed this is that I can't work on <code>three-rs...
  • Artifice Hotfix 1

    2020-12-08 19:47:20
    <div><p>Issue to track/discuss hotfix (, ). <p>To be fixed: - [X] RE1: RGB LEDs broken #1587 - [x] Authors list on Authors screen still empty #1600 - [ ] ~~~GCS: Rfm Bind Wizard Appears Broken #1602~...
  • Hotfix/14.4.1

    2021-01-08 05:26:19
    <div><p>Merge Hotfix/14.4.1 into develop <p>PR submission checklist: <ul><li>[x] I have considered adding unit tests where possible.</li><li>[x] I have considered adding accessibility improvements for...
  • Android Hotfix

    2018-03-03 09:26:21
    Hotfix:让应用能够在无需重新安装的情况实现更新,帮助应用快速建立动态修复能力。 热补丁技术在2015年开始爆发,目前已经是非常热门的Android开发技术。Android平台出现了一些优秀的热更新方案,主要可以分为两...

    Hotfix:让应用能够在无需重新安装的情况实现更新,帮助应用快速建立动态修复能力。

    热补丁技术在2015年开始爆发,目前已经是非常热门的Android开发技术。Android平台出现了一些优秀的热更新方案,主要可以分为两类:
    - 基于multidex的热更新框架,包括Nuwa、Tinker等;
    - 基于native hook方案,如阿里开源的Andfix和Dexposed。

    1. 热更新流程

    1. 线上检测到严重的Crash
    2. 拉出bugfix分支并在分支上修复问题
    3. jenkins构建和生成补丁
    4. app通过push主动拉取补丁文件
    5. 将bugfix合并到master上

    2. Hotfix原理

    ClassLoader

    Java在运行时加载对应的类是通过ClassLoader来实现的,ClassLoader本身是一个抽象来,Android中使用PathClassLoader类作为Android的默认的类加载器, PathClassLoader其实实现的就是简单的从文件系统中加载类文件。PathClassLoade本身继承自BaseDexClassLoader,BaseDexClassLoader重写了findClass方法, 该方法是ClassLoader的核心。

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
        Class c = pathList.findClass(name, suppressedExceptions);
        if (c == null) {
            ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + pathList);
            for (Throwable t : suppressedExceptions) {
                cnfe.addSuppressed(t);
            }
            throw cnfe;
        }
        return c;
    }

    BaseDexClassLoader将findClass方法委托给了pathList对象的findClass方法,pathList对象是在BaseDexClassLoader的构造函数中new出来的, 它的类型是DexPathList。

    DexPathList.findClass

    public Class findClass(String name, List<Throwable> suppressed) {
        for (Element element : dexElements) {
            DexFile dex = element.dexFile;
    
            if (dex != null) {
                Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
                if (clazz != null) {
                    return clazz;
                }
            }
        }
        if (dexElementsSuppressedExceptions != null) {
            suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
        }
        return null;
    }

    遍历dexElements列表,然后通过调用element.dexFile对象上的loadClassBinaryName方法来加载类,如果返回值不是null,就表示加载类成功,会将这个Class对象返回。

    而dexElements对象是在DexPathList类的构造函数中完成初始化的。

    this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions);

    makeDexElements所做的事情就是遍历我们传递来的dexPath,然后一次加载每个dex文件。

    3. 美团Robust方案原理

    Robust

    Robust插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码,插入过程对业务开发是完全透明。如State.java的getIndex函数:

    public long getIndex() {
            return 100;
        }

    被处理成如下的实现:

    public static ChangeQuickRedirect changeQuickRedirect;
        public long getIndex() {
            if(changeQuickRedirect != null) {
                //PatchProxy中封装了获取当前className和methodName的逻辑,并在其内部最终调用了changeQuickRedirect的对应函数
                if(PatchProxy.isSupport(new Object[0], this, changeQuickRedirect, false)) {
                    return ((Long)PatchProxy.accessDispatch(new Object[0], this, changeQuickRedirect, false)).longValue();
                }
            }
            return 100L;
        }

    可以看到Robust为每个class增加了个类型为ChangeQuickRedirect的静态成员,而在每个方法前都插入了使用changeQuickRedirect相关的逻辑,当 changeQuickRedirect不为null时,可能会执行到accessDispatch从而替换掉之前老的逻辑,达到fix的目的。

    如果需将getIndex函数的返回值改为return 106,那么对应生成的patch,主要包含两个class:PatchesInfoImpl.java和StatePatch.java。

    PatchesInfoImpl.java:

    public class PatchesInfoImpl implements PatchesInfo {
        public List<PatchedClassInfo> getPatchedClassesInfo() {
            List<PatchedClassInfo> patchedClassesInfos = new ArrayList<PatchedClassInfo>();
            PatchedClassInfo patchedClass = new PatchedClassInfo("com.meituan.sample.d", StatePatch.class.getCanonicalName());
            patchedClassesInfos.add(patchedClass);
            return patchedClassesInfos;
        }
    }

    StatePatch.java:

    public class StatePatch implements ChangeQuickRedirect {
    @Override
    public Object accessDispatch(String methodSignature, Object[] paramArrayOfObject) {
    String[] signature = methodSignature.split(“:”);
    if (TextUtils.equals(signature[1], “a”)) {//long getIndex() -> a
    return 106;
    }
    return null;
    }

    @Override
    public boolean isSupport(String methodSignature, Object[] paramArrayOfObject) {
        String[] signature = methodSignature.split(":");
        if (TextUtils.equals(signature[1], "a")) {//long getIndex() -> a
            return true;
        }
        return false;
    }
    

    }

    客户端拿到含有PatchesInfoImpl.java和StatePatch.java的patch.dex后,用DexClassLoader加载patch.dex,反射拿到PatchesInfoImpl.java这个class。拿到后,创建这个class的一个对象。然后通过这个对象的getPatchedClassesInfo函数,知道需要patch的class为com.meituan.sample.d(com.meituan.sample.State混淆后的名字),再反射得到当前运行环境中的com.meituan.sample.d class,将其中的changeQuickRedirect字段赋值为用patch.dex中的StatePatch.java这个class new出来的对象。这就是打patch的主要过程。通过原理分析,其实Robust只是在正常的使用DexClassLoader,所以可以说这套框架是没有兼容性问题的。

    4. 微信Tinker

    tinker

    简单来说,通过完全使用了新的Dex,那样既不出现Art地址错乱的问题,在Dalvik也无须插桩。当然考虑到补丁包的体积,不能直接将新的Dex放在里面。但可以将新旧两个Dex的差异放到补丁包中,这里可以调研的方法有以下几个:

    dex-method

    • BsDiff;它格式无关,但对Dex效果不是特别好,而且非常不稳定。当前微信对于so与部分资源,依然使用bsdiff算法;
    • DexMerge;它主要问题在于合成时内存占用过大,一个12M的dex,峰值内存可能达到70多M;
    • DexDiff;通过深入Dex格式,实现一套diff差异小,内存占用少以及支持增删改的算法。

    微信使用了DexDiff算法。

    该方案的优势:

    • Dalvik全量合成,解决了插桩带来的性能损耗;
    • Art平台合成small dex,解决了全量合成方案占用Rom体积大, OTA升级以及Android N的问题;
    • 大部分情况下Art.info仅仅1-20K, 解决由于补丁包可能过大的问题;

    事实上,DexDiff算法变的如此复杂,怎么样保证它的正确性呢?微信为此做了以下三件事情:

    • 随机组成Dex校验,覆盖大部分case;
    • 微信200个版本的随机Diff校验, 覆盖日常使用情况;
    • Dex文件合成产物有效性校验,即使算法出现问题,也只是编译不出补丁包。

    每一次DexDiff算法的更新,都需要经过以上三个Test才可以提交,这样DexDiff的这套算法已完成了整个闭环。

    详情参见:微信Tinker的一切都在这里,包括源码(一)


    参考

    1. Android 热修复专题
    2. 微信Tinker的一切都在这里,包括源码(一)
    3. HotFix原理介绍及使用总结
    4. Android热更新方案Robust
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,571
精华内容 2,628
关键字:

hotfix