3. Atlas整体架构分层:Bundle容器、Dalvik/ART适配、动态部署层职责与边界
Atlas(原名AABundle)是阿里团队打造的组件化框架,其架构核心并非简单的插件化,而是旨在实现“动态部署”与“组件化”的深度融合。理解Atlas的架构分层,是进行和RePlugin对比选型的前提。Atlas整体采用三层架构,每层职责清晰,边界严格,通过明确的信任链路相互协作。
3.1 架构边界与分层模型
Atlas将整个移动应用运行时划分为三个层次,由下至上依次为:Dalvik/ART适配层、Bundle容器层、动态部署层。各层之间通过预定义的接口进行通信,下层为上层提供基础能力,上层负责业务编排与生命周期管理。
分层模型的核心边界在于:
- Dalvik/ART适配层:负责屏蔽Android虚拟机差异,提供统一的类加载、资源加载和Dex处理能力。这是框架的“底座”,不与任何业务逻辑耦合。
- Bundle容器层:定义Bundle(即独立功能模块)的生命周期、通信协议、隔离策略。它是“运行时容器”,负责管理所有非宿主Bundle的安装、启动、卸载。
- 动态部署层:负责Bundle的版本管理、下载、校验、灰度发布。它是“业务策略层”,与后端CDN和配置中心对接,实现用户无感知的热更新。
设计意图:这种分层使得底层的虚拟机适配逻辑可以被复用,容器层保持稳定,动态部署层可以按需迭代。即便未来Android虚拟机发生重大变化(例如ART的进一步演进),也只需修改最底层的适配层,而无需重写整个框架。
3.2 各层组件职责详解
3.2.1 Dalvik/ART适配层(Runtime Adaptation Layer)
该层是最底层,直接与Android系统虚拟机交互。它的核心职责是解决类隔离和资源合并问题。Atlas不依赖Android标准的DexClassLoader,而是通过修改PathClassLoader的parent链,实现多Bundle之间的类可见性控制。
- 类加载引擎:为每个Bundle创建独立的ClassLoader,并建立“宿主优先 -> 依赖Bundle -> 自身”的链式委托模型。
- 资源加载器:通过合并AssetManager的方式,使得宿主和所有已加载Bundle的资源ID全局唯一且不冲突。
- Dex优化器:处理MultiDex的拆分与合并,解决Dalvik下65535方法数限制,并在ART下处理预编译(dex2oat)的兼容性。
3.2.2 Bundle容器层(Bundle Container Layer)
这是框架的运行时可执行环境,负责管理每一个Bundle的安装、激活、停用和卸载。容器层不关心Bundle的具体业务逻辑,只关注状态转换和资源分配。
- APK管理器:负责物理文件的操作,包括将云端下载的Bundle APK复制到私有目录、执行Dex优化、记录安装版本元数据。
- Bundle生命周期管理器:定义并调度Bundle的生命周期回调,包括
onInstall、onLoad、onUninstall等。 - 通信桥:提供跨Bundle的调用机制,支持同步的IPC调用和异步的EventBus模式,避免Bundle之间直接依赖。
关键公共配置示例:Bundle容器需要知晓每个Bundle的依赖关系。这个配置通常以JSON形式存储在宿主的assets目录下,容器层启动时加载。
{
"bundles": [
{
"name": "business_home",
"version": 12,
"dependencies": ["common_util", "network_core"],
"mustPreload": true
}
]
}
3.2.3 动态部署层(Dynamic Deployment Layer)
这是Atlas区别于纯组件化框架的关键。它使得业务模块可以在不发布新版本的情况下进行更新。该层完全运行在应用进程内,但控制策略来自于远端配置中心。
- 版本巡检器:定时或按策略向配置中心发起请求,比对本地Bundle的版本ID与远端最新版本ID。
- 补丁生成器:在下载完整Bundle APK或差分补丁后,调用bspatch工具(通过JNI)合成新的APK文件。
- 灰度引擎:根据设备ID、用户分组、随机百分比等维度,决定是否允许某个设备下载并激活新版本Bundle。这是保障线上稳定性的最后一道防线。
3.3 数据流与控制流
一次典型的“动态部署”完整流程可以清晰展示各层的协作:
- 数据流起点:动态部署层的“版本巡检器”获取到远端配置,发现
business_homeBundle有新版本。 - 控制流下发:动态部署层指示“灰度引擎”检查当前设备是否命中灰度。若命中,则调用“补丁生成器”下载差分补丁。
- 数据流入容器:补丁合成完成后,动态部署层将新APK文件的路径传递给Bundle容器层的“APK管理器”。
- 容器层执行:APK管理器执行安装操作,调用Dalvik/ART适配层的“类加载引擎”和“资源加载器”,注册新的类与资源。
- 最终呈现:Bundle生命周期管理器启动新的Bundle实例,旧的Bundle实例被回收。
3.4 控制流与信任链路
Atlas的信任链路贯穿三个层次,任何一层验证失败都会导致部署流程终止:
| 信任链路层级 | 验证内容 | 失败处理 |
|---|---|---|
| L1: 宿主签名 | 宿主自身的APK签名证书 | 应用拒绝启动 |
| L2: Bundle签名 | 远端下载的Bundle APK是否与宿主证书一致 | 拒绝安装,删除文件 |
| L3: 容器层验证 | Bundle版本号是否高于当前版本;依赖Bundle是否已加载 | 回滚到旧版本 |
| L4: 动态部署策略 | 灰度条件是否匹配;补丁完整性校验(MD5/SHA1) | 不激活新版本,保持旧版本 |
3.5 选型权衡与风险点
- 权衡一(隔离性 vs 灵活性):Atlas的类加载链式委托模型是“可见即可调”,这使得Bundle之间调用近乎透明,但代价是运行时如果发生类冲突,排查难度比RePlugin的高。(RePlugin采用更严格的类隔离。)
- 权衡二(动态部署 vs 性能):动态部署层在安装Bundle时会调用Dex优化操作(尤其在ART上),此过程可能造成几十毫秒的卡顿。需要在首次安装或版本切换时做异步处理。
- 风险点1:Dalvik/ART差异:在Dalvik虚拟机下,Atlas需要自行处理Dex分拆;在ART下则需要处理dex2oat预编译产生的锁文件冲突。适配层处理不当会导致应用启动崩溃。
- 风险点2:Bundle依赖循环:容器层如果检测到Bundle间的依赖形成闭环,会导致ClassLoader栈溢出。框架没有自动环路检测,需要在构建工具链中强制约定。
3.6 落地步骤与验收标准
若要在项目中引入Atlas的三层架构,建议按照以下步骤推进:
| 步骤序号 | 职责归属 | 关键动作 |
|---|---|---|
| 1 | 基础选型 | 确认Gradle版本,引入atlas-core依赖,配置Bundle的Gradle插件 |
| 2 | 宿主改造 | 修改Application.onCreate,初始化Atlas框架;配置assets/bundle_config.json |
| 3 | Dalvik/ART适配 | 在低端Android设备(API 19-23)上做Dex优化验证,处理NoClassDefFoundError |
| 4 | 容器层搭建 | 编写Demo Bundle,验证安装、启动、资源加载、类调用链路 |
| 5 | 动态部署集成 | 搭建配置中心API,编写版本巡检与灰度逻辑,测试补丁差分包 |
| 6 | 全链路验收 | 编写验收用例,覆盖信任链路的每一层校验 |
验收标准(Pass / Fail):
- 在Dalvik和ART设备上,Bundle的首次安装时间均不超过200ms(异步情况下)。
- 动态部署更新后,冷启动首次打开新Bundle,类加载无异常,资源无错乱。
- 信任链路验证:篡改Bundle签名后,应用应拒绝加载并输出WARNING日志。
- 灰度引擎规则正确:白名单设备能更新,非白名单设备无法更新。