💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
#### **概述** 通过本章的学习,让同学们了解什么是插件化,插件化与组件化两种思想的区别,以及插件化的原理和难点。 插件化并不像热修复使用的那么广泛,因为一般的App并不需要插件化,只有航母级别的App(淘宝,优酷等)这些门户型的apk才会在实际开发中使用到插件化。 #### **插件化出现的背景** * APP体积越来越大,功能模块越来越多。 比如手机淘宝,淘宝内部集成了彩票、聚划算等功能 * 模块越来越多,模块耦合度高,协同开发沟通成本极大 * 方法数超过65536(64K限制),占用内存过大 #### **如何解决?** * 将一个大的APK按照业务分割成多个小的apk 只有用户点击到那个小apk,才会动态加载那个小apk。 * 每个小的apk既可以独立运行又可以作为插件运行 #### **插件化的优点** * 业务模块基本完全解耦 * 高效并行开发(编译速度更快) * 按需加载,内存占用更低等等 #### **基本概念** * 宿主:主APP可以加载插件,也成为Host。 宿主APP里面只有基本的类库和功能 * 插件:插件APP,被宿主加载的APP。可以是跟普通APP一样的apk文件。 各个业务功能模块独立出来的apk,这些apk模块不需要安装在手机中。可以直接被宿主加载其内部的dex文件和资源文件。 * 插件化:将一个应用按照宿主插件的方式改造就叫插件化。 核心在于与普通的apk相比,普通的App的所有代码都运行在一个apk文件中,插件化后,各自的代码运行在各自的插件apk中,通过插件的协作来完成整个功能 **结构相比** ![](https://box.kancloud.cn/21d6e4ac0323bd0bebef2a5f029f228f_1428x396.png) 之所以将插件apk以so库形式存在,是为了和普通的APP应用相统一。 下图就是解压后的优酷apk的lib中的armeabi文件中的很多的so库文件,其中红色圈起来的都是插件apk以so库存在,还有很多没有标记,这些只是一部分 ![](https://box.kancloud.cn/2323b7122bdc5946a220f4a391d80a43_365x906.png) #### **概念解析对比** **插件化和组件化** * 组件化是一种编程思想,而插件化是一种技术 * 组件化是为了代码的高度复用性而出现的。 将常用的功能模块封装成独立的lib,供需要它的任何APP使用 * 插件化是为了解决应用越来越大而出现的 插件化主要是将各个关联性不是很强的业务独立的封装到自己的apk中,通过插件部署到宿主apk中完成功能的实现 二者没有任何冲突,可以在插件化过程中使用组件化思想 **插件化和动态更新** * 与动态更新一样,都是动态加载技术的应用 * 动态更新是为了解决线上bug或小功能的更新而出现的 动态更新的使用频率更高,对原来工程改造相对比较小,原理相对简单 * 插件化是为了解决应用越来越大而出现的 插件化对原来工程的改造很大,原理更加复杂 ![](https://box.kancloud.cn/6a9f294c4f6646ff630817df1b2e1654_773x427.png) #### **相关知识** * android ClassLoader加载class文件原理 * Java反射原理 * Android资源加载原理 * 四大组件加载原理 要想完成插件化框架的构架,工作量很大,基本上个人是无法独立完成的,一般都是一个小团队来完成。 **清单文件(Mainfest处理)的处理** ![](https://box.kancloud.cn/aac18b27e50d007069b28d7168ca6899_1297x484.png) 重点研究如何修改这个流程完成清单文件的合并 **插件类的加载** ![](https://box.kancloud.cn/4185f4b8d0c4488aca4e51b80a3582e4_1321x466.png) 每个插件都是一个apk,都有其自己的dex文件,dex文件包含了所有的类,字节码。市面上的插件化框架基本上都如上图来加载插件中的类的。 如上图 这里的bundle就是插件的意思 首先会区分宿主apk和插件apk,因为宿主apk已经安装到了手机中,Android虚拟机会给宿主apk创建它自己的ClasLoader,无须手动创建。插件apk并没有安装到手机中,Android系统不会为这些插件apk创建ClasLoader,要想加载插件中的apk文件,必须具备ClasLoader,这时候插件化框架就起作用了。插件化框架会为每个插件apk创建它需要的自己的ClasLoader,就可以使用自己的ClasLoader加载对应的class文件。 这里需要研究的2个问题 * 如何自定义ClasLoader加载类文件 * 如何调用插件apk文件中的类 #### **模拟插件化框架管理步骤** **资源加载** ![](https://box.kancloud.cn/a3e433f729953f31be9a696cd1c1a902_670x627.png) 上图,我们可以得到:真正起作用的是AssetManager这个类。Resources类主要完成resource由资源ID到资源文件的映射。 安装到系统的apk,系统会为这apk创建AssetManager类和Resources类,所以安装到系统的apk可以直接通过context获取到资源,那么没有安装到系统的apk,系统不会为这些apk创建AssetManager类和Resources类,这时候插件化框架就起作用了:动态创建插件apk所需要的资源加载类。 目前市面上流行的插件化框架的思路: ![](https://box.kancloud.cn/9d658162714f4406c7d72008b83c5c0d_543x523.png) 1. 所有的Bundle Res资源都是加入到DelegateResources 2. Bundle Install的时候讲Res、So等目录通过反射加入到(AssetManager.addAssetPath) 3. 通过不同的packageId来区分各个Bundle的资源ID 4. 覆盖getIdentfier方法,兼容5.0以上的系统 **核心技术** * 处理所有apk文件中的清单文件 * 管理宿主apk中所有的插件apk信息 * 为每个插件apk创建对应的类加载器,资源管理器