- 宿主:也叫主程序,指可以动态加载并运行插件的程序
- 插件:运行在宿主上的程序,可以免安装运行
- 插件化:将项目分为宿主和插件部分,插件按需加载
- 热修复:动态更新类或者函数,一般用于修复 BUG
Jessie 在 AndroidManifest 中预埋了一个 MainInitProvider,用来做一些初始化工作。
MainInitProvider 会跟随着宿主 APP 的 Application 一起启动,
它会通过启动 JessieDaemonService 来主动唤醒一个名为 :jcdm 的守护进程(Daemon 进程)。
JessieDaemonProvider 会伴随着 Daemon 进程启动, 它会自动扫描已安装的 APK,并自动将他们加载入内存。 以后的所有插件 APK 的安装都会在 Daemon 进程中进行。
安装插件的入口是 Jessie.install(apk),
它会通过 AIDL 获取与 Daemon 进程通信的 IJessieProgramManager 实例。
在 Daemon 进程中,与之通信的是 JessieProgramManagerImpl,
它会调用 PluginManager.install(apk) 来安装插件。
PluginManager 内部维护了一张表,记录了所有安装过的插件程序(Program)。
整个插件的安装过程都是在 Daemon 进程中。
每个插件都拥有自己单独的进程,进程分配的任务也是在 Daemon 进程进行的。
负责进程分配任务的类为 ProcessDispatcher。
ClassLoader 是类加载器,用来加载 Class。 ClassLoader 是插件运行的核心,任何插件化方案和热修复方案都离不开 ClassLoader。
在 Android 中,有 2 种最常见的 ClassLoader: PathClassLoader 用来加载当前运行的 App 的 Class, DexClassLoader 用来动态加载 APK 或 DEX 文件中的 Class。 要是实现插件化,必须要使用 DexClassLoader。
Jessie 中的每个插件都有自己的 ClassLoader —— PluginDexClassLoader,它们都继承制至 DexClassLoader。 PluginDexClassLoader 破坏了 ClassLoader 原有的双亲委托机制, 也就是说它会优先加载自己的 Class,在没有找到的情况下才会去寻找父 ClassLoader 中的 Class。
我们知道 Android 中的 Activity 等四大组件等都有自己的生命周期,并且都必须要在 Manifest 文件中申明之后才能使用。但是插件是动态加载进来的,除非在宿主的 Manifest 中预埋一些 Activity 的坑位,否则很难让插件的 Activity 正常运行。
./gradlew installPlugin为了在测试过程中更快的定位到问题,建议使用源码透明的 APP 来测试。
下面是一些建议的测试 APP。
| 名称 | 源码 | APK |
|---|---|---|
| 开源中国 | Gitee | 应用宝 |
| Flutter-OSC | Github | Github |
| Termux | Github | F-Droid |
| AndroidFire | Github | fir.im |
| ARouter | Github | Github |
| flutter-go | Github | Github |
| WanAndroid | Github | Github |
| GSYGithubApp | Github | 蒲公英 |
| GSYGithubAppKotlin | Github | 蒲公英 |
| GSYGithubAppWeex | Github | 蒲公英 |
| GSYGithubAppFlutter | Github | 蒲公英 |