Android插件化开发之动态加载的类型

https://segmentfault.com/a/1190000005113493

基本信息

  • Author:kaedea

  • GitHub:android-dynamical-loading

现在网络上有许多关于动态加载的介绍的文章,谈及的关键词汇有动态加载、插件化、热部署、热修复等,对于一些刚接触这方面开发技术的人来说,可能容易混淆。

虽然我在动态加载系列的文章中或多或少有谈到这些概念的区别,但是我觉得认识这些区别对于使用动态加载技术还是挺重要的,所以特别开这个新的文章进行分析。

动态加载的类型

无论是插件化、热部署还是热修复,这些技术的根源都可是说是动态加载,这也是我把“动态加载”作为这个系列文章主题的原因。

动态加载,就是在程序运行时,加载外部的可执行文件并运行。这里的运行时就是指应用冷启动并开始工作后;外部可以是可以是SD卡,可以是data目录,也可以是jniLib目录,这些可执行文件是没有随着应用一起编译的。

Android的动态加载按照工作机制的不同,可以分为虚拟机层动态加载和Native层动态加载两大类。

运行在虚拟机

简单来说就是只用JAVA代码搞定的类型。

基于虚拟机的动态加载技术的核心是类加载器ClassLoader,通过它我们能够加载一些新的类,这种方式也是目前大部分技术文章谈到的加载方式。其中,根据ClassLoader使用方式的不同,又演变出“热部署”、“插件化”、“热修复”等技术。

热部署

加载外部可执行文件的ClassLoader实例与原APP的ClassLoader实例是互相独立的(不在同一棵代理树上),加载进来的新的类与原APP(宿主)里存在的类互相独立,根据Java对类的定义,因为这些类的ClassLoader不同,所以他们即便包名和类名一致,或者有继承关系,他们也属于不懂的类。所以以这种方式加载进来的类与原有的类不能互通,不能污染宿主原有的类,适合用来动态加载一些独立的业务,比如一些推广的游戏,在宿主上提供一个入口,用户不需要安装游戏就能运行。因为这种方式起到不用安装就能部署游戏的作用,所以称为热部署。

插件化

加载外部可执行文件的ClassLoader实例与宿主的ClassLoader实例不是互相独立的,用宿主的ClassLoader加载过的类就无法从外部可执行文件中再次加载,它们可以共用一个公共库,习惯上把外部可执行文件称为插件。插件里可以存放公共库里一些借口的实现类,可以有一些新的Activity或者Service等组件,可以把一些宿主里的业务挪到插件中,插件可以自主升级,不用随着宿主APP发版。

热修复

在使用插件化技术的同时,也可以使用插件中的新的类来替换宿主同名的类,这样就能修复宿主中原有的类存在的BUG。相比插件化,热修复因为不需要考虑组件和res资源的问题,所以相对简单得许多,要保证插件种新的类的加载要在加载宿主中原有类的之前。

拆分DEX

相信大家都知道打包DEX时65536方法数超标问题,也就是一个DEX只能有65536个方法,因此有了multi-dex的解决方案,把本来只有一个的DEX,拆分成复数以上的DEX,运行时挨个加载进来,这其实也算是一种动态加载,只不过实现过程对开发者是透明的。

除此之外,还有另一种拆分DEX是用于减少冷启动的时间的。冷启动是指应用第一次从用户点击到完成初始化工作的全部过程。随着现在APP的体积不断增长,一些APP的DEX文件十分庞大,APP在启动的时候,单单加载所有的DEX文件就需要非常多的耗时,所以用户点击APP的时候会有一个明显的卡顿过程。因此有一种拆分DEX的方案是“拆分一个启动闪屏用的DEX,里面只存放启动闪屏界面需要用到的类,因此非常小,其他类放到其他DEX里面”,启动的时候因为只需要加载闪屏的DEX,所以非常快,APP进入闪屏后,通过异步任务去完成其他DEX的加载,就能消除卡顿的过程。

第一种拆分DEX是官方支持的,开发者只需要打开multi-dex功能即可;第二种拆分DEX则需要开发者自己设计。

基于ClassLoader的动态加载都有个共同的特点,就是新的类一旦加载进内存了,就无法再次替换了,所以无法在运行时候升级功能,需要重启APP才能生效。

运行在Native

有另一种动态加载方式是工作在Native层的,相比于ClassLoader,在Native层的动态加载不需要重新启动APP就能生效,这类的加载有 加载SO库 和 基于JNI HOOK 的热修复。

加载SO库

加载SO库是最常见的Native动态加载,我们项目经常中使用SO库,编译APP的时候,SO并不会参与编译,会原封不动被拷贝到APK包里的lib目录下,安装APK的时候,系统会扫描lib文件夹下支持当前设备CPU类型(比如arm或x86)的SO库(APK包会带有多种CPU类型对应的SO库,安装的时候只需要对应类型的)并拷贝到系统安装目录,APP在运行时可以调用 System#loadLibrary 方法动态加载对应的SO库,此外还可以调用 System#load 加载指定路径上的SO库。

现在的APK里面往往带有非常多的SO库,而APP运行时只需要用到对应CPU类型的SO库,因此把SO库从APK包里剥离出来也是APK瘦身的有效手段。

JNI HOOK

基于JNI HOOK的热修复技术的代表框架有阿里巴巴的 AndFix。Android中,修复BUG的方式就是更新类的方法,和ClassLoader通过加载新的类来更换方法的实现的想法一样,AndFix 也是通过更换方法的做法来实现热修复,不过做法比较取巧。Android中执行Native方法的时候,会去SO库中查找对应的C/C++方法,而 AndFix 先把普通Java方法用Native方法代替,再通过更换不同SO库还更换Native方法的实现。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292396.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UITableView的优化原理

2019独角兽企业重金招聘Python工程师标准>>> 当我们下啦一个 UITableView时,如果没有做优化,只是简单的实现功能代码如下,这样当我们有上百条tableviewcell的时候,我们滑动的非常快时会非常费内存,当然苹果…

深入浅出Mybatis系列(一)---Mybatis入门[转]

最近两年 springmvc mybatis 的在这种搭配还是蛮火的,楼主我呢,也从来没真正去接触过mybatis, 趁近日得闲, 就去学习一下mybatis吧。 本次拟根据自己的学习进度,做一次关于mybatis 的一系列教程, 记录自己的学习历程&…

C# 图像模板匹配并标注

01—需求这个是粉丝在我的技术群提的一个需求1、 模板匹配 :功能:(1)在一张大图像中,选取一小块区域作为模板(2)可在大图像中匹配到模板图像和位置。模板匹配是图像处理中最基本、最常用的匹配方…

深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap[转]

上篇《深入浅出Mybatis系列(七)---mapper映射文件配置之insert、update、delete》介绍了insert、update、delete的用法,本篇将介绍select、resultMap的用法。select无疑是我们最常用,也是最复杂的,mybatis通过resultMa…

北大保送、硕博连读!《西游记》红孩儿扮演者现成中科院博士!

全世界只有3.14 % 的人关注了爆炸吧知识本文转自:募格学术86版《西游记》可以说是很多人的记忆,男女老幼几乎都看过这个版本,虽然已经过去三十多年,但如今依旧是经典无法超越之作。看过86版《西游记》的小伙伴应该都还记得里面牛魔…

Android插件化开发之运行未安装apk的activity

1、介绍 我们知道PathClassLoader是一个应用的默认加载器(而且他只能加载data/app/xxx.apk的文件),但是我们加载插件一般使用DexClassLoader加载器,所以这里就有问题了,其实如果对于开始的时候,每个人都会认为很简单,…

理解UI线程——SWT, Android, 和Swing的UI机理

2019独角兽企业重金招聘Python工程师标准>>> 在做GUI的时候, 无论是SWT, AWT, Swing 还是Android, 都需要面对UI线程的问题, UI线程往往会被单独的提出来单独对待, 试着问自己, 当GUI启动的时候, 后台会运行几个线程? 比如 1. SWT 从Main函数启动 2. Swing 从Ma…

C#多线程开发-并发集合中的ConcurrentQueue

前言大家好,我是阿辉。上一篇博文简单介绍了C#中支持并发的数据字典,简单举例说明比较了常规集合与ConcurrentDictionary的读写速度。下来简单介绍其中一个线程安全队列ConcurrentQueue;ConcurrentQueue队列我们不陌生,在数据结构这门课中就有…

一个人动情之后的表现......

1 卖家能有什么坏心思呢(via.城与橙与澄,侵删)▼2 严重怀疑传了答案▼3 别说我还真没留意到(素材来源网络,侵删)▼4 领导说“辛苦了”,你要怎么回答▼5 哦吼(素材来源网络&#…

线性代数第五版吉尔伯特课后答_线性代数同济第五版第六章课后习题答案!

搜集 | 整理 | 测试 | 小愉免责声明:以下资源或软件均来自互联网,仅供学习和交流使用,如有侵权请联系删除,请勿用于商业和非法途径等,如有法律纠纷与本人无关!本文未经允许,不得转载&#xff0…

sql长整型_SQL 性能优化梳理

先简单梳理下Mysql的基本概念,然后分创建时和查询时这两个阶段的优化展开。1 基本概念简述1.1 逻辑架构第一层:客户端通过连接服务,将要执行的sql指令传输过来第二层:服务器解析并优化sql,生成最终的执行计划并执行第三…

网络的东西南北

前一陣子連續出差, 加上許多的內部會議, 搞的差點想去撞牆把自己搞昏之後就可以休息一下. 但是家中還有嗷嗷待哺的嬰兒需要爸爸幫他洗屁屁, 所以只有咬牙繼續撐下去. 不過這兩個月來, 不過在公司內部還是外部, 我都收到一樣類似的老問題那就是:(認識我的…

K8s 中使用 cert-manager 申请免费 Https 证书

K8s 中使用 cert-manager 申请免费 Https 证书Intro最近在尝试将自己的应用从自己用 kind 部署的一个 k8s 集群迁移到 Azure 的 AKS 上,其中一个问题就是 https 证书,原来的 k8s 集群是放在 nginx 后端的并没有直接管理 https 证书,https 证书…

为什么要学数学?因为它真的没用啊!

全世界只有3.14 % 的人关注了爆炸吧知识数学之用无用之用有一天,表妹过来问了我两个问题:数学有什么用?那些深奥的公式对于普通人有什么意义?相信大多数人都有这个疑问,但总是找不到一个标准答案。问老师,他…

UI设计教程-界面设计构图

九宫格构图,圆心点放射形构图,三角形构图,SF字形构图。 1.九宫格网格构图 这种版式主要运用在分类为主的一级页面,起到功能分类的作用。 通常在界面设计中,我们会利用网格在界面进行布局,根据水平方向和垂直…

Android之最好理解的Binder机制

转载:http://weishu.me/2016/01/12/binder-index-for-newer/ Binder学习指南 发表于 2016-01-12 | 92条评论 | 34011次阅读毫不夸张地说,Binder是Android系统中最重要的特性之一;正如其名“粘合剂”所喻,它是系统间各个组件…

sql年月日24小时制_24小时制的「无码」真人秀,令人叫绝

几年前,我们总说互联网给世界带来了巨大的变化。到了现在,没想到自媒体的发展居然也能改变生活。但大家知道吗,其实早在20年前,美国那边就曾因“直播”掀起过不小的风浪——还是尺度挺大的那种。以至于毒师看过以后,整…

HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题...

背景HangFire有个很奇怪的现象,就是即使你设置的循环作业是一天一次,但是每次作业执行很长时间,我们假设是1小时,那么差不多在开始执行之后的30分钟之后,如果还在执行job,系统就会自动帮你重新开启了新的job执行。也就…