热修复部分原理和问题

2016-09-08  本文已影响64人  一洼世界

2017.2.1 更
年前经过研究,腾讯的开源Tinker 更强大和配置简单,并且有专门的网站管理分发更新差异包,并且有微信作为实践,适用性高。(逃
----------------------------------------------分割线-----------------------------------------------
2016.11.11 更
偷了一张图: 开源的热更新挺稳定的 手机QQ目前所用的 [RocooFix] 原理
(https://github.com/dodola/RocooFix/tree/master/app)

Paste_Image.png

----------------------------------------------分割线-----------------------------------------------

详细的教程(倾向于原理)
倾向于使用教程
** Numa 傻瓜式修复 **

1.dex分包:
编译失败,
android 2.3之前无法安装,dex文件过大(系统只分配了5M)
解决办法:分成两个dex,第二dex以资源形式存在,在Application的onCreate中注入。

2.分包原理 DexClassLoader 和 PathClassLoader。
pathList 查找, dexElement 保存dex数组。
遍历dexElements. 通常数组只有一个元素,apk安装包的classes.dex. 通过反射强行将dex文件添加到此 dexElements中.

3.热补丁修复技术的原理。
如果两个dex中存在相同的class文件会怎样?
先从第一个dex中找,找到了直接返回,遍历结束。而第二个dex中的class永远不会被加载进来。
简而言之,两个dex中存在相同class的情况下,dex1的class会覆盖dex2的class。

4.加载补丁原理:
dex保存在这个位置 BaseDexClassLoader–>pathList–>dexElements
1.apk的classes.dex可以从应用本身的DexClassLoader中获取。
2.patch_dex(补丁)的dex需要new一个DexClassLoader加载后在获取。(先加载)
3.分别通过反射获取dex文件,重新合并成一个数组,然后赋值给本身的ClassLoader的dexElements

5.CLASS_ISPRREVERIFIED问题:解决方法是在所有类的构造方法中添加System.out.println(AntilazyLoad.class);( 这个是个别打包在hark.dex中),
*1.不能在源码中直接加载,AntilazyLoad.class找不到,编译不通过。
*2.绕过编译,使用javassist操作字节码,直接注入代码。 Android Studio项目Gradle构建的,编译-打包-签名都是自动化的。

6.Gradle是通过一个一个Task执行完成整个流程的,其中肯定也有将所有class打包成dex的task。
在Gradle 1.5以上新出的 ** Transfrom ** Api。

7.注册Transfrom : (一种解决方式. 坑较多。)

8.javassist使用: (太复杂 有时间去学)

9.Gradle: Gradle本身的领域对象主要有Project和Task,Project为Task提供执行上下文,所有的Plugin要向Project中添加用于配置的Property,要么向Project添加不同的Task,一个Task表示一个逻辑上较为独立的执行过程,比如编译Java源代码,拷贝文件,打包Jar文件,甚至可以是执行一个系统命令。

上一篇下一篇

猜你喜欢

热点阅读