记:初学习插件化和热更新

本篇文章学习于以下链接,主意为用自己方式理解和记录
动态加载技术插件化讲解:转载于https://segmentfault.com/a/1190000004062866
插件化和热更新的小梳理:转载于https://www.jianshu.com/p/704cac3eb13d

简单来说,
插件化意为:把需要实现的功能或模块提取出来,减少APK的大小,在需要使用的地方,再进行相应的加载
热更新意为:主要从修复bug的角度考虑,不采用传统的下载、安装apk的方式,在用户不知不觉中修改bug
(本篇学习文章侧重点在热更新)

一.插件化

实际应用场景:动态换肤、动态加载资源、或宿主APK体积太大,把不是必须的模块动态加载
优点:
(1)将项目可以模块化分开,降低了耦合度,可以并行开发,加快了开发速度
(2)可以避免安卓市场的规则
(3)减少主项目的方法数,可以避免65536的问题
缺点:
(1)并行开发后合并模块,有可能会出现各种奇怪的问题
(2)动态加载的插件会出现不兼容的问题在一些老的版本手机

二.热更新

热更新的作用是为了及时迅速的修改线上版本的bug
热更新中,最重要的就是类加载器
类加载器包括PathClassLoaderDexClassLoader,源码贴于下面:

public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super(dexPath, null, null, parent);
    }

    public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        super(dexPath, null, librarySearchPath, parent);
    }
}
   public class DexClassLoader extends BaseDexClassLoader {
        public DexClassLoader(String dexPath, String optimizedDirectory,
                              String librarySearchPath, ClassLoader parent) {
            super(dexPath, new File(optimizedDirectory), librarySearchPath, parent);
        }
    }
    public class BaseDexClassLoader extends ClassLoader {
    ...
        public BaseDexClassLoader(String dexPath, File optimizedDirectory, String libraryPath, ClassLoader parent){
            super(parent);
            this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
        }
    ...
    }

加上后期理解可知:
(1)PathClassLoaderDexClassLoader都继承于BaseDexClassLoader
(2)PathClassLoader只能加载已经安装到APP系统中的文件(data/app目录);DexClassLoader可以安装任意目录下的dex/jar/apk/zip文件
(3)DexClassLoader相比于PathClassLoader多一个optimizedDirectory的参数。由第二点可知道,DexClassLoader允许安装dex/jar/apk/zip文件,而他们本质都是压缩文件,所以知道多的
optimizedDirectory参数是一个解压缩后的目录
(4)类加载器通过DexPathList的findClass()方法找到他说加载到的class,其中DexPathList的构造器使用makeDexElements()得到Element集合,形式为用“;”分号隔开的file文件目录拼接的字符串

原理
经过对PathClassLoader、DexClassLoader、BaseDexClassLoader、DexPathList的分析,我们知道,安卓的类加载器在加载一个类时会先从自身DexPathList对象中的Element数组中获取(Element[] dexElements)到对应的类,之后再加载。采用的是数组遍历的方式,不过注意,遍历出来的是一个个的dex文件。
  在for循环中,首先遍历出来的是dex文件,然后再是从dex文件中获取class,所以,我们只要让修复好的class打包成一个dex文件,放于Element数组的第一个元素,这样就能保证获取到的class是最新修复好的class了(当然,有bug的class也是存在的,不过是放在了Element数组的最后一个元素中,所以没有机会被拿到而已)。

原理 .png

摘自:https://juejin.im/post/5a0ad2b551882531ba1077a2


我的理解:在父类BaseDexClassLoader中,通过DexPathList的构造方法调用makeDexElements()方法获取Elements集合。其中集合中的每个Elements对应一个dex,一个dex对应多个Class文件。然后通过DexPathList的findClass()方法,使用刚才获取到的Elements集合,找到对应的Class文件。我们要做的就是把补丁,放入elment集合的最前面,然后把这个组合成一个新的集合,包装成一个dex。通过反射放入DexPathList。由于双亲加载机制的特点,当找到第一个Class,后面的错误有Bug的Class将不会再加载,这样就实现了热更新。
双亲加载机制:如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委托给自己的父加载器,每一层的类加载器都是如此,因此所有的类加载请求最终都应该传送到顶层的Bootstrap ClassLoader中,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己加载

图解.jpg

总结:热更新使用的是类加载机制。类加载包含PathClassLoader和DexClassLoader,它们都继承于BaseDexClassLoader,不同之处在于PathClassLoader只能加载安卓默认安装目录下的文件即(data/apk)中,而DexClassLoader可以安装任意目录下的文件(即dex/apk/jar/zip)。DexClassLoader会比PathClassLoader构造方法多一个参数,是用于存储解压文件的目录。在BaseDexClassLoader中,构造方法获取到dexPathList,又通过dexPathList构造方法的makeDexElements()得到Element集合,每个element对应一个dex文件,一个dex文件对应多个class。dexPathList中的findClass能帮助我们从makeDexElements()得到的Element集合找到有问题的Class。我们要做的就是把补丁Elment数组和原来的Elment数组整合成一个新的数组(补丁在前),然后把这个Elment数组给到dexPathList的Element集合中去。这样由于双亲加载机制,只会加载一次class,这样错误的bug的class仍在里面但一直不会加载到。

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

推荐阅读更多精彩内容