说起插件化,先谈谈为什么使用插件化技术呢,因为当我们的app业务很多的话,里面可能会融合其他的app,拿美团举例吧,美团app里有美团买菜,酒店民宿,骑车等等,那这个主app里单拿出一个美团买菜,可能就有自己的app,这个app里又有自己的业务,使用插件化技术可以动态加载apk,减小安装包的大小,而且比较灵活,可以动态的增删业务。

那么如何实现插件化呢,分为如下几步:

  1. 首先要搞清楚宿主app如何动态加载插件类.

  2. 加载到宿主app的插件类如何启动

  3. 插件的资源如何加载。

宿主app如何加载插件的类

那么先开始说第一步,宿主app如何加载插件的类,就要明白Android类的加载原理,Android类加载器分为系统加载器BootclassLoder,应用加载器pathclassLoder加载app自己的类,还有动态加载器DexPathclassloder,可以自定义加载路径。pathclassLoder和DexPathclassloder的父类是Basedexclassloder . Android类加载是双亲委派机制,每个类只能被加载一次,如果已经被加载过就直接返回结果,如果没有被加载过,会递归交给最顶层的父类加载,如果父类都没有加载过,就交给自己加载,类加载过程是通过pathlist.findclass方法,到element.findClass(name, definingContext, suppressed)最终到 dexFile.loadClassBinaryName(name, definingContext, suppressed),pathlist是在Basedexpathclassloder中初始化的,pathlist就是Dexpathlist,在Dexpathlist里通过makeDexElements()方法来获取Element数组,一个Element对应一个dexfile.

所以想要让宿主加载插件的类就是通过反射获取到Element数组,把插件的的Element数组和宿主的的Element数组合并成一个新的数组,然后重置给宿主就可以了

加载进插件的类

第二步就是加载进插件的类,插件的类并没有在宿主清单文件里注册,那怎么启动插件的类呢?

想要启动插件的类,首先需要在清单文件注册一个占位的activty,在ActivitymannagerService检查activity的合法型的时候通过反射把插件的类替换成占位activity,等ActivitymannagerService检查完,启动activity之前把占位activity反射替换成插件的类,这样最后启动的就是插件的类了。

插件的资源如何让加载

在Android中,资源文件是通过Resources对象来加载的。每个APK都有一个独立的Resources对象,用于加载它自己的资源文件。

在Android插件化中,我们可以创建一个新的Resources对象来加载插件中的资源文件。这个Resources对象的AssetManager是通过反射创建的,可以加载任意路径的APK文件。

插件就这样加载进宿主app了。

Android类的启动文章 https://juejin.cn/post/6847902222294990862