NuWa热修复原理基础详细解说——初识,热修复

前言:不得不跟正在看这篇文章的宝宝们说一句,作为菜鸟的我,看了很多大神的文章,对于热修复也是初识,有什么写的不对的地方,还望大家指导,此篇文章也作为自己的笔记,便于自己总结。

做这个笔记之前我看了一下几篇文章,记下了好的解说图,和好的观点,附上链接,表示感谢:

热修复,没你想的那么难

热补丁动态修复框架小结

安卓热补丁动态修复技术介绍 

一、什么是热修复:

相信很多人第一次听说热修复的时候也是一脸茫然,那么我就用自己的话来跟大家讲解一下。

当一个已经上线的APP突然发现一个严重的bug的时候,除了重新发版,让用户重新下载覆盖安装以外,还有没有别的方法来解决呢?如果可以有一个动态修复的方法就好了,那就是热补丁动态修复技术,也就是我们说的热修复。向用户下发Patch,在用户无感知的情况下,修复bug问题。这里用到的是android dex分包方案,后面会具体解释如何实现的。

这里我们先说一下Android的插件化,Android插件化分为三大块:热部署动态加载资源四大组件动态加载

分别举例:

热部署 ------------------------------热修复

动态加载资源-------------------动态换肤

四大组件动态加载----------模块化开发

二、基于的原理——心急吃不了热豆腐

首先,就要从Android的ClassLoader体系来说起:

ClassLoader顾名思义,就是在Java中加载一个类需要用到的。

在Android中有三大ClassLoader,分别为URLClassLoader,PathClassLoader,DexClassLoader.其中:URLClassLoader:只能用于加载jar文件,但是由于 dalvik 不能直接识别jar,所以在 Android 中无法使用这个加载器。

这里我们重点来说后面这两个加载类:

PathClassLoader:前面说过热修复是用到了dex分包方案(后面会说什么是dex文件),那么这个PathClassLoader就是用来去找dex文件的类。当apk安装后,PathClassLoader会去读取/data/dalvik-cache/dex文件,例如我们安装了一个包名为com.meijia.xxx的apk,那么安装后就会在/data/dalvik-cache目录下,生成一个data@app@com.meijia.xxx-1.apk@classes.dex的ODEX文件(后面会讲解什么是ODEX文件),而PathClassLoader找的就是这个ODEX文件,如果说找不到这个文件,就证明apk还没有安装,报错就是ClassNotFoundException。

DexClassLoader:顾名思义,DexClassLoader就是用来加载dex的加载类,就是从.jar和.apk类型的文件内部加载classes.dex文件。可以用来执行非安装的程序代码,也就指的是插件中的apk代码。

它的构造函数包含四个参数:

1.dexPath:就是目标类所在的APK或者jar文件的全路径。

2.dexOutputDir:就是dex在APK或者jar文件中解压后的dex文件存放路径

3.libPath:指目标类中所使用的C/C++库存放的路径

4.classLoad:是指该装载器的父装载器,一般为当前执行类的装载器

到这里,我们就知道了1.PathClassLoader在这里是作为类加载器,2.DexClassLoader是用来加载classes.dex文件的。继续。

PathClassLoader和DexClassLoader都是继承BaseDexClassLoader这个类,看源码如图:

这里我们通过注释可以看到1.其中DexPathList pathList就是多dex的结构列表。2.其中pathList里面包含一个Element [ ] dexElements数组就是dex列表,每一个element就是一个dex文件。

那好,当PathClassLoader加载类加载的时候会遍历Element [ ] dexElements,如果找到对应类则加载,找不到,就会继续从下一个dex文件中查找,那么我们就明白了,试想,如果我们将补丁插件dex文件插入到Element [ ] dexElements的最前面,理论上不同dex中有相同的类名存在时,会优先加载第一个类,找到了就返回,不会再继续查找下一个dex文件了,这就是我们说的基于dex分包的热修复的原理。

到这里,我们就知道了热修复就是在ClassLoader(类加载器)中插入一个dex文件。

那么什么是dex文件?什么又是ODEX文件呢?它们和class是什么关系?为什么Android只能识别dex文件,不能直接识别class文件呢?

先看一下class的结构,如图(摘自邓凡平老师博客)

我们可以看到一个class文件中包含很多版本信息,常量等信息。

dex文件就是将整个Android项目中的所有class文件合并成一个或者几个dex文件,当两个或几个class文件中有重复的字符串,那么dex就只存一份就可以了,换种说法就是dex是对class的压缩。

所以,在Android dalvik虚拟机中是无法识别一个class文件的,因为他们的结构不同,一个dex文件的结构如图

然后什么是ODEX呢,Android dalvik虚拟机也不是直接识别dex文件的,当APK被安装的时候,虚拟机会实现一次优化,就是将dex文件转换成odex文件,这次转换是为了对不同的手机硬件做对应的优化,而class转换成dex,是针对不同平台的优化,两者意义上是不同的。

然而,就在这优化过程中,在虚拟机启动的时候会有很多参数,其中有一项叫做verify的选项,当这个选项被开启之后,就会实行一个类的校验,具体校验内容就是,如果static方法、private方法、构造函数等,其中的直接引用(第一层关系)到的类都在同一个dex文件中,那么该类就会被打上CLASS_ISPREVERIFIED标志

校验过程如下:

一旦这个类CLASS_ISPREVERIFIED标志被打上,那么我们也就不能从别的dex文件中替换这个类了,那么我们之前说的在Element [ ]中插入dex的方法就无用了,知道了原因,办法就好想了。

不就是如果这个dex中的类没有引用其他dex文件中的类,就会被打上CLASS_ISPREVERIFIED
标志么?那么我们就让他引用就好了。

三、如何阻止CLASS_ISPREVERIFIED标记

到这里,试想,如果我们在所有的类的构造函数中,引用一个其他dex文件中的类的方法的话,是不是就可以防止被打上CLASS_ISPREVERIFIED标记了。

其中,hack.dex文件是要在最先加载进来的,不然如果当应用启动的时候,hack.dex没有先加载进来的话,这些引用它的类,就会报错,找不到hack.dex中的AntilazyLoad这个类。

那么问题来了?

如何去修改一个类?又如何在应用启动时最先加载hack.dex这个文件呢?

不同的修复方案的解决办法是不同的,这里就不一一介绍了,因为如果要说的话,要说的东西太多,我觉得自己还说不好,就搜罗网络上热门的方案大致以下几种开源框架。

https://github.com/dodola/HotFix 

https://github.com/jasonross/Nuwa 

https://github.com/bunnyblue/DroidFix

其中鸿洋大神的文章是用HotFix解说的:HotFix解说

涛哥的文章是用Nuwa解说的:Nuwa解说

总结:在学习一项新知识的时候,需要很大的耐心,对于基础不是很好的同学,会在学习的过程中发现越来越多自己不懂的地方,这时候请不要烦躁,请静下心来,反复对敲,不懂的地方更是要耐心的去找资料去学习,当你明白了一项新知识以后,你会发现,你学到的比你想象的还要多。以此共勉,加油~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容