第1章:模块与埋点状态的定义
1.1 模块边界划分
在Android大型工程中,模块间埋点状态流转的核心问题是边界定义。没有清晰的模块边界,状态就会混乱、重复、丢失。
| 边界类型 | 定义 | 示例 |
|---|---|---|
| 物理边界 | Gradle模块(api/implementation依赖) | :feature:login、:core:tracking |
| 逻辑边界 | 业务领域上下文 | 登录域、支付域、搜索域 |
| 运行时边界 | 进程/线程/生命周期边界 | 主进程与推送进程分离 |
关键原则:物理边界决定编译时依赖,逻辑边界决定状态名称空间,运行时边界决定状态同步方式。三个边界必须对齐,否则会出现跨模块状态穿透问题。
1.2 埋点事件类型
每个模块产生的埋点事件可以按职责分为四类,这四类是状态流转的基本单元:
- 行为事件(Action Event):用户或系统的显式操作,如点击、滑动、网络请求完成。
- 状态事件(State Event):某个模块内部状态发生变化,如登录态从“未登录”变为“已登录”。
- 边界事件(Boundary Event):跨模块的入口/出口事件,如从主页模块进入详情模块。
- 元事件(Meta Event):描述埋点系统自身行为的控制事件,如初始化完成、缓存命中失败。
在架构上,状态事件和边界事件是需要跨模块流转的核心类型,其余两类一般只在模块内部消费。
1.3 状态实体定义
状态实体是埋点状态流转中携带的数据载体。一个完整的状态实体必须包含以下字段:
// 伪代码:埋点状态实体定义
class TrackState {
String eventId; // 全局唯一事件ID
String moduleId; // 产生模块标识
String eventType; // 事件类型枚举
long timestamp; // 事件发生时间戳
String stateKey; // 状态键,如 "login_status"
String stateValue; // 状态值,如 "logged_in"
Map<String, String> metadata; // 扩展元数据
String traceId; // 全局追踪链路ID
}
核心约定:所有模块必须使用统一的状态实体格式进行跨模块传递,禁止自定义结构。通过强制
eventId 全局唯一和 traceId 链路追踪,可以解决埋点数据丢失后难以定位的问题。
1.4 模块间埋点状态流转结构
下图展示了在一个多模块Android工程中,埋点状态从产生到消费的完整流转路径:
常见风险:模块在没有通过埋点SDK的情况下直接操作状态总线,会导致信任链路断裂。所有埋点事件必须经过埋点SDK的校验和封装,才能发布到状态总线。
1.5 落地第一阶段的验收标准
| 验收项 | 标准 | 验证方式 |
|---|---|---|
| 模块边界清单 | 所有参与流转的模块已列出物理边界与逻辑边界 | 架构评审文档 |
| 事件类型定义 | 四类事件已明确区分,且跨模块事件已标识 | 代码扫描(检查事件类型枚举) |
| 状态实体格式 | 所有模块使用统一的TrackState结构 |
Lint规则 + Code Review |
| 信任链路 | 埋点SDK作为唯一入口,状态总线不可被模块直接调用 | 架构约束验证测试 |
1.6 选型权衡:统一SDK vs 分散上报
| 维度 | 统一埋点SDK(推荐) | 分散上报 |
|---|---|---|
| 维护成本 | 低(集中管理) | 高(各模块自建) |
| 信任链路 | 强(中心校验) | 弱(难以统一验证) |
| 灵活性 | 中(需遵守SDK规范) | 高(可自定格式) |
| 跨模块流转 | 原生支持 | 需要额外适配 |
| 适合规模 | 大型工程(模块 > 20) | 小型工程或实验性项目 |
在第一章节中,我们通过定义清晰的模块边界、事件类型和状态实体格式,为后续的跨模块状态流转打下基础。下一步将进入“分层职责”的讨论,确立各层在状态流转中的具体角色。