您的位置:首页 > 移动开发 > Android开发

Android 热补丁的一些总结

2016-07-18 01:00 302 查看
常见方案:淘宝的Dexposed、支付宝的AndFix以及Qzone

缺点:

补丁不能支持所有的修改,例如AndroidManifest;只能针对单一客户端版本,随着版本差异变大补丁体积也会增大

优点:

补丁大小均在300K;

1天覆盖率达到70%以上;

修复bug

非常适合使用在灰度阶段(可以快速对同一批用户验证修复效果,若发布版本出现问题或紧急漏洞,传统方式需要单独灰度验证修改,然后重新发布新的版本。利用补丁技术,我们只需要先上线小部分用户验证修改的效果,最后再全量上线即可)。

远端调试

所以补丁机制非常适合使用在远端调试上。即我们需要具备只特定用户发送补丁的能力,这对我们查找问题非常有帮助。

A/BTest数据统计

例如若我想对同一批用户做两种test,传统方式无法让这批用户去安装两个版本。使用补丁技术,我们可以方便的对同一批用户更换补丁版本。

热拔插:代码改变被应用、投射到APP上,不需要重启应用,不需要重建当前activity。

场景:适用于多数的简单改变(包括一些方法实现的修改,或者变量值修改)
温拔插:activity需要被重启才能看到所需更改。

场景:典型的情况是代码修改涉及到了资源文件,即resources。

Tips:温拔插需要重启Activity,因为资源文件是在Activity创建时加载,所以必须重启Activity来重载资源文件。

冷拔插:app需要被重启(但是仍然不需要重新安装)

InstantRun

http://www.jianshu.com/p/2e23ba9ff14b
http://www.tuicool.com/articles/uQJjA3b
[b]InstantRun原理:[/b]

运行Gradle任务来生成增量.dex文件(这个dex文件是对应着开发中的修改类) Android Studio会提取这些.dex文件发送到App Server。

在有Instant Run的环境下:一个新的App Server类会被注入到App中,与Bytecode instrumentation协同监控代码的变化。

同时会有一个新的Application类,它注入了一个自定义类加载器(Class Loader),同时该Application类会启动我们所需的新注入的App Server。于是,Manifest会被修改来确保我们的应用能使用这个新的Application类。(这里不必担心自己继承定义了Application类,Instant Run添加的这个新Application类会代理我们自定义的Application类)

这个自定义的classloader也要继承BaseDexClassLoader,因为BaseDexClassLoader里有个DexPathList,这个所谓的List里存的是多个dex的文件信息,所以当某段代码修改时,只需编译和替换相应的dex文件即可

源码中可以看到,Studio其实就是利用反射,将自己的IncrementalClassLoader设置成app中默认ClassLoader的parent,这样就拦截了所有类加载的动作,从而实现了对多个dex文件的动态加载。

可以参考:http://www.cnblogs.com/coding-way/p/5443718.html

经过实际测试:

android:name="com.android.tools.fd.runtime.BootstrapApplication"






方案对比:

微信:


根据BsDiff的改进算法DexDiff生成两个版本的差异dex,在用户手机上根据老dex还原出新dex。

问题:如何做到不刷新?

QQ空间

分包方案:就是把多个dex文件塞入到app的classloader之中,但是android dex拆包方案中的类是没有重复的,如果classes.dex和classes1.dex中有重复的类,当用到这个重复的类的时候,系统会选择哪个类进行加载呢?

理论上,如果在不同的dex中有相同的类存在,那么会优先选择排在前面的dex文件的类,如下图:



补丁的方案,把有问题的类打包到一个dex(patch.dex)中去,然后把这个dex插入到Elements的最前面。

但是会有问题,解决方法如下:

if (ClassVerifier.PREVENT_VERIFY) {

System.out.println(AntilazyLoad.class);

}

其中AntilazyLoad类会被打包成单独的hack.dex,这样当安装apk的时候,classes.dex内的类都会引用一个在不相同dex中的AntilazyLoad类,这样就防止了类被打上CLASS_ISPREVERIFIED的标志了,只要没被打上这个标志的类都可以进行打补丁操作。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: