4. RePlugin插件生命周期管理

4.1 本章定位与架构边界

插件生命周期管理是 RePlugin 插件化框架的核心能力层,它定义了插件从“外部资源包”转变为“可运行组件”再到“完全卸载”的完整过程。与 Atlas 基于“bundle 按需挂载”的策略不同,RePlugin 采用“独立 APK + 动态注册”的模型,生命周期的边界更清晰,但控制点也更为集中。

架构边界界定:

  • 宿主侧边界:只负责提供 ClassLoader 创建入口和插件管理服务(Loader 进程)。
  • 插件侧边界:插件 APK 自身不感知生命周期调度,仅暴露入口组件(Activity/Service/Receiver)。
  • 框架侧边界:RePlugin 框架(包括宿主 Loader 与插件 Local 层)承担全部生命周期编排。

4.2 分层模型与组件职责

分层 组件/模块 生命周期职责
宿主层 PluginManagerClient
(宿主进程)
发起安装/卸载请求;维护插件状态表;提供 Hook 注册接口
Loader 层 PluginServiceHelper
TaskExecutor
解析插件包;创建 DexClassLoader;分配组件坑位;回调预/后置 Hook
插件层 插件内 Application
入口 Activity/Service
接收生命周期回调;执行自身初始化/销毁逻辑;不参与调度决策
安全校验层 SignatureVerifier
TrustChainValidator
安装时校验签名与信任链;启动时校验插件完整性(可选)

4.3 安装、启动、销毁三阶段流程与 Hook 点设计

RePlugin 将插件生命周期划分为三个主阶段,每个阶段内部包含若干原子步骤,并在关键步骤前后插入 Hook 回调,供宿主或插件进行干预。

4.3.1 安装阶段

  1. 资源拷贝:将插件 APK 文件从外部存储复制到宿主私有目录(data/data/<package>/plugins/)。
  2. 签名校验:验证插件 APK 签名是否与宿主允许的签名列表匹配。
  3. 组件扫描:解析 AndroidManifest.xml 中声明的 Activity、Service、Receiver、ContentProvider,并建立组件注册表。
  4. 坑位分配:为组件分配宿主预埋的“坑位”(占位 Activity/Service),更新坑位映射表。
  5. 数据库记录:将插件信息写入 PluginDB,标记为“已安装”状态。

安装阶段 Hook 点:

Hook 名触发时机可修改内容
onBeforeInstall拷贝开始前插件路径、签名校验规则
onAfterVerify签名校验完成后是否允许安装(返回 false 则中断)
onComponentRegistered组件注册表写入后组件别名、坑位编号

4.3.2 启动阶段

  1. 插件类加载:创建 DexClassLoader,加载插件 APK 中的 Dex 和资源。
  2. 初始化插件 Application:反射调用插件内 Application 的 onCreate 方法(若插件声明了)。
  3. 组件实例化:通过坑位映射查找目标组件,创建实例并调用其生命周期方法(如 Activity 的 onCreate)。
  4. 重定向上下文:替换组件内 Context 为插件资源桥接上下文,确保资源与宿主隔离。

启动阶段 Hook 点:

Hook 名触发时机可修改内容
onBeforeLoadClassDexClassLoader 创建前自定义 ClassLoader 结构、类白名单
onAfterCreateApp插件 Application 初始化后向 Application 注入宿主依赖
onComponentPrepared组件实例化完成但未回调 onCreate组件参数、Intent 数据

4.3.3 销毁阶段

  1. 组件销毁:调用插件内组件的 onDestroy / onStop 等方法。
  2. 释放 ClassLoader:断开 DexClassLoader 引用,允许 GC 回收。
  3. 清理资源表:从组件注册表中移除该插件条目;释放坑位。
  4. 删除文件:可选择删除插件 APK 文件及数据目录。
  5. 更新状态:将 PluginDB 中状态标记为“已卸载”或删除记录。

销毁阶段 Hook 点:

Hook 名触发时机可修改内容
onBeforeUnload组件销毁前取消未完成任务、持久化数据
onAfterClean资源清理完成后执行回调通知宿主其他模块

4.4 控制流与监控链路

下图展示了 RePlugin 插件从“开始安装”到“卸载完成”的完整控制流,以及三个阶段的 Hook 锚点分布。

RePlugin 插件生命周期控制流与 Hook 锚点 RePlugin 插件生命周期控制流与 Hook 锚点 ① 安装阶段 子步骤 1. 拷贝 APK ➜ 签名校验 2. 组件扫描 ➜ 坑位分配 3. 入库标记“已安装” onBeforeInstall onAfterVerify ② 启动阶段 子步骤 1. 创建 DexClassLoader 2. 初始化插件 Application 3. 实例化组件 ➜ 重定向 Context onBeforeLoadClass onComponentPrepared ③ 销毁阶段 子步骤 1. 组件 onDestroy 2. 释放 ClassLoader 3. 清理资源表 4. 更新 DB 状态 onBeforeUnload 信任链路与安全边界 • 安装阶段:宿主必须对插件 APK 进行 签名校验,拒绝未签名或签名不匹配的插件。 • 启动阶段:框架验证插件 信任链证书,确保插件未被中间人篡改。 • 销毁阶段:框架确保所有组件引用先释放,再删除文件,防止内存泄漏与文件锁定。

4.5 选型权衡与风险点

风险点一:安装过程无事务回滚

RePlugin 在安装阶段未采用数据库事务 + 文件备份机制。如果在“拷贝 APK”后“签名校验”失败,宿主目录下会残留不完整插件文件。需要宿主自行在 onAfterVerify Hook 中做清理补偿。

风险点二:启动阶段 DexClassLoader 泄露

每次启动都会创建新的 DexClassLoader,若调用方未及时回收引用,将导致 DexClassLoader 和对应 Dex 文件长期驻留内存。建议在 onBeforeUnload Hook 中主动清除所有外部引用。

与 Atlas 的选型权衡:

决策维度RePluginAtlas
安装粒度全量安装整个插件 APK可按 bundle 增量挂载
启动开销每次创建独立的 DexClassLoader,CMS 压力较大复用宿主 ClassLoader,启动更快
卸载彻底性可完全删除插件文件bundle 仅卸载类,文件需额外清理
Hook 扩展性8 个预定义钩子 + 自定义扩展支持 bundle 级 AOP 切面

4.6 落地步骤与验收标准

落地步骤

  1. 初始化 Hook 注册中心:在宿主 Application onCreate 中调用 PluginManager.addLifecycleHook() 注册所有自定义回调。
  2. 实现签名校验插件:在 onAfterVerify 中使用宿主预埋的公钥验证插件签名哈希。
  3. 配置组件坑位表:在宿主 AndroidManifest.xml 中预留足够数量的占位 Activity/Service。
  4. 异常补偿:在 onBeforeUnload 中序列化插件当前状态,并清理临时文件。
  5. 单元测试覆盖:编写安装 → 启动 → 销毁三阶段的集成测试,验证 Hook 回调执行顺序和参数正确性。

验收标准

  • 安装一个 10MB 的插件 APK,从文件复制到组件注册完成,耗时 ≤ 800ms(中端设备)。
  • 连续安装/卸载 50 次后,宿主 /data/data/<package>/plugins/ 目录下无残留文件。
  • 销毁后调用 PluginManager.isInstalled() 返回 false;内存快照中不存在该插件的 DexClassLoader 强引用。
  • 每个 Hook 点通过日志输出被正确调用,入参上下文有效。

经验建议:

RePlugin 的“独立 ClassLoader 模型”在插件隔离性上优于 Atlas,但代价是包体积和安装时间。如果你的业务场景中插件数量超过 20 个,应优先考虑“预加载 + 懒卸载”策略,在 onBeforeUnload Hook 中设置引用计数,避免频繁重建 ClassLoader。