Now in Android 项目结构分析:这个 App 是如何搭建起来的?
核心观点
Now in Android 的项目结构并不是为了让开发更简单,而是为了让大型团队能够长期维护同一个代码库。
理解 NIA 的关键,不是记住它有多少个 Module,而是理解这些 Module 分别承担什么职责,以及它们之间如何协作。
整体结构
NIA 大致可以分为五个部分:
app/ feature/ core/ sync/ benchmark/ build-logic/它们共同构成了整个应用。
app:应用装配层
app模块负责将所有能力组装成一个完整的应用。
主要职责包括:
- Application 初始化;
- MainActivity 入口;
- Navigation 配置;
- 依赖注入初始化;
- Feature 模块整合。
它本身不承载复杂业务逻辑,而是承担“组装者”的角色。
可以将其理解为:
App = Feature + Core 的装配工厂。
feature:业务功能层
Feature 模块按照业务进行拆分,例如:
feature:foryou feature:search feature:bookmarks feature:topic每个模块负责:
- Compose Screen;
- ViewModel;
- UI State;
- 与 Repository 交互。
其目标是:
让业务功能能够独立开发和演进。
这种拆分方式天然适合多人协作。
core:共享能力层
Core 模块提供整个应用共享的能力。
例如:
core:model core:data core:database core:network core:ui core:designsystem它们通常不直接面向用户,而是为 Feature 提供基础设施支持。
例如:
- model:领域模型;
- data:Repository 实现;
- database:Room 数据库;
- network:网络请求;
- ui:共享 UI 组件;
- designsystem:统一设计规范。
其目标是:
避免重复实现公共能力。
sync:同步层
NIA 引入了专门的数据同步模块。
其职责包括:
- 后台同步数据;
- 保证本地数据与远程数据一致;
- 管理同步策略。
这种设计体现了离线优先(Offline First)的思想。
在普通项目中,这一层往往被合并到 Repository 中。
benchmark:性能工程层
NIA 提供了完整的性能基础设施,包括:
- Macrobenchmark;
- Baseline Profile。
其目标是:
- 测量启动性能;
- 发现性能回退;
- 优化首次启动体验。
对于大型应用而言,性能属于工程能力的一部分。
build-logic:构建逻辑层
这是许多人第一次阅读 NIA 时最困惑的部分。
其作用是:
将重复的 Gradle 配置抽离出来。
例如:
- Android Library 配置;
- Compose 配置;
- Kotlin 配置;
- Hilt 配置。
通过 build-logic,整个项目的构建规则得到统一。
代价是:
- 学习成本增加;
- Gradle 理解门槛提高。
整个项目是如何协作的?
用户点击 App 图标后,大致流程如下:
也可以抽象为:
其中:
- Feature 负责业务;
- Core 提供共享能力;
- App 完成组装。
依赖关系
NIA 的依赖关系是单向的:
即:
- app 可以依赖 feature;
- feature 可以依赖 core;
- core 不依赖 feature;
- feature 之间尽量避免直接依赖。
这种设计的价值在于:
- 降低耦合;
- 提升可维护性;
- 支持独立演进。
为什么会显得复杂?
因为 NIA 优先考虑的是:
- 长期维护;
- 多人协作;
- 工程稳定性。
而不是:
- 快速开发;
- 最少代码量;
- 新人友好。
对于小型项目而言,这种复杂度可能难以带来足够收益。
但对于大型项目而言,这些边界和约束能够降低系统失控的风险。
我的结论
Now in Android 的项目结构,本质上是一种工程化分层。
它试图回答的问题不是:
“如何最快做出一个 App?”
而是:
“如果这个 App 需要被十几名开发者维护五年,它应该如何组织?”
因此,阅读 NIA 时不应关注:
“这个 Module 我需不需要复制?”
而应该关注:
“这个 Module 在解决什么问题?我的项目是否也存在这个问题?”
好的项目结构并不是最复杂的结构。
而是复杂度与问题规模相匹配的结构。