1. 在现代 Android 开发中,如何组织代码结构才能既易于维护又方便测试?本文将分享一个基于 Jetpack Compose + Hilt + Clean Architecture + MVI 构建的项目实战经验。
2. 为什么选择这套架构?
- Clean Architecture: 将业务逻辑与 UI、框架解耦,哪怕以后想把 Retrofit 换成 Ktor,也只需改动 Data 层。
- MVI: 强制性的单向数据流。相比于 MVVM,MVI 通过 Intent 和 State 解决了 UI 状态碎片化的问题,让调试变得异常清晰。
3. 项目结构分层演示
com.example.cleanmvicompose
├── domain # 领域层:包含纯净业务逻辑 (Model, Repository Interface, UseCase)
├── data # 数据层:负责数据来源 (Remote API, Repository Impl)
├── ui # UI层:MVI 状态管理与 Compose 组件渲染
│ ├── user # 用户功能模块 (Intent, State, ViewModel, Screen)
│ └── theme # 主题样式 (Color, Theme, Type)
└── di # 依赖注入层:Hilt 模块配置 (NetworkModule, RepositoryModule)
4. 核心代码片段
- MVI 核心循环:展示如何通过 Flow 在 ViewModel 中处理 Intent 并更新 State。
- Domain 层 UseCase:展示如何编写一个只负责单一业务逻辑的类。
5. 避坑指南:消失的 Hilt 绑定 (这是本文的干货点) 在项目初期,我遇到了一个让人头秃的报错:[Dagger/MissingBinding] UserApiService cannot be provided。
排查过程:明明在 NetworkModule 里写了 fun provideUserApiService(),为什么 Hilt 还是说找不到?
- 解决方案:
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides // 敲黑板!这个注解绝对不能漏
@Singleton
fun provideUserApiService(): UserApiService {
return UserApiService()
}
}
- 心得:Hilt 的魔法全靠注解。漏掉一个 @Provides,整个依赖注入大厦就会轰然倒塌。