ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

【Jetpack Compose进阶学与练】第12课:Compose项目完整目录结构

【Jetpack Compose进阶学与练】第12课:Compose项目完整目录结构 前言前面已经学习了Compose UI、ViewModel、MVI架构、Room数据库、Navigation导航、SavedStateHandle。现在从代码走向工程正式项目一般采用单Activity架构同时思考分包、模块化区分业务模块、基础common公共模块。本节课讲解单Activity的含义标准分包结构模块化和普通包分包的区别多模块项目的优势与代价。知识点清单什么是单Activity架构为什么现在优先选择单Activity Navigation‑Compose单Activity内部可以拥有大量逻辑页面依靠导航回退栈管理标准app模块内部分包ui / viewmodel / repository / datacommon公共模块职责存放工具、扩展、基础组件、常量模块化vs仅仅包划分模块化的收益以及带来的编译配置代价完整目录示例plaintextapp主应用模块└─ src/main/java/com.demo.myapp├─ ui # UI层 Compose页面、组件、导航路由│ ├─ home│ ├─ article│ ├─ login│ └─ navigation # AppRoute 路由常量、导航管理├─ viewmodel # ViewModelMVI Intent / UiState / Effect密封类├─ repository # Repository仓库层└─ data # 数据源层├─ local # Room数据库、Dao、Entity└─ remote # Retrofit api、网络请求common公共基础模块Android library└─ src/main/java/com.demo.common├─ base # 基础定义、基础密封类├─ component # 通用Compose基础组件通用加载页、错误重试页面├─ extension # Kotlin扩展函数├─ utils # 工具类└─ constant # 全局常量MainActivity.kt单Activity入口packagecom.demo.myappimportandroid.os.Bundleimportandroidx.activity.ComponentActivityimportandroidx.activity.compose.setContentclassMainActivity:ComponentActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{AppTheme{AppNavHost()//整个应用全部导航宿主所有页面全部在这里管理}}}}逐行解读单Activity架构是什么整个App只有一个Activity(MainActivity)不再为每一个业务页面新建独立Activity。所有业务页面全部是Compose的可组合函数页面跳转完全交给Navigation‑Compose的回退栈管理。优势Activity之间跳转会有系统动画、额外生命周期开销单Activity消除大量Activity跳转开销页面之间共享导航栈跨页面传参更加方便。劣势整个App全部的页面都跑在同一个Activity生命周期页面的独立销毁需要依靠导航回退栈pop。app模块内部分包只是包划分不是模块拆分同一个module下面不同package分包适合中小型项目。uiCompose页面、可复用UI组件只做界面渲染转发用户Intent。viewmodel存放ViewModelUiState、Intent、Effect密封类业务逻辑层。repository仓库层协调本地Room和远程Retrofit。data数据源local本地数据库remote网络API。注意分包不等于模块化分包只是同一个模块下面划分不同的文件夹package。common公共library模块真正模块化新建Android librarycommon独立成library模块app模块依赖common。common里面放通用组件、工具类、扩展函数、基础样式后续如果新增业务模块也可以依赖common。common模块禁止依赖app主模块单向依赖公共基础层不能反向依赖上层业务。模块化多module适用场景与代价适合中大型项目把不同业务拆成独立业务modulemodule‑article、module‑user。收益业务之间代码隔离业务边界清晰可以多人并行开发编译增量构建改动一个业务模块不会全部重编译。代价Gradle配置复杂度上升模块之间不能直接访问内部类模块之间通信需要定义对外暴露接口导航跨模块路由处理会变得麻烦。小型项目不建议过度拆分多模块只做包分包就足够。单向依赖原则common基础模块 ← 业务模块 ← app主模块下层不能反向依赖上层业务一旦反向依赖会出现循环依赖编译报错。容易踩坑❌ common公共模块里面写业务页面代码common只能放通用基础不能写业务。❌ 模块之间循环依赖app依赖commoncommon又反过来依赖app直接编译失败。❌ 小型项目强行过度拆分很多业务module增加项目维护成本。✅ 中小型项目单Activity app内部分包大型项目单Activity common基础模块 多个独立业务模块保持单向依赖。多元化习题练习习题1【基础‑改错题】项目里面common基础模块引用了app主模块里面的业务ViewModel会出现什么问题答案会形成循环模块依赖Gradle编译直接报错common作为下层基础模块不应该感知上层业务业务逻辑只能放在app或者业务module当中。解读依赖只能单向下层被上层依赖下层不能回过来引用上层。习题2【基础‑代码修改题】单Activity里面setContent{}内部只调用AppNavHost为什么不在Activity里面写业务页面Compose答案Activity只做应用入口所有页面、导航逻辑统一交给AppNavHost后续导航逻辑修改全部在Compose层维护入口Activity尽量保持精简。解读Activity尽量轻量化业务下沉到Compose导航体系。习题3【进阶‑补充代码题】简述分包package划分文件夹和模块化新建library module二者的区别。答案分包仍然处于同一个Gradle模块只是源码文件夹分类编译的时候整个模块一起编译适合中小型项目。模块化新建独立的Gradle library模块有独立build.gradle模块之间显式声明依赖适合大型项目支持并行开发和增量编译。解读很多新手混淆分包和模块化不是新建文件夹就算模块化。习题4【综合‑逻辑应用题】为什么现在Android Compose项目主流选择单Activity架构而不是传统一个页面一个Activity答案传统多Activity跳转有额外Activity生命周期开销页面之间数据共享麻烦单Activity依靠Navigation‑Compose管理回退栈所有页面都是Compose组件页面切换开销更小统一的转场动画更容易实现。解读但要注意页面释放完全依靠导航回退栈pop没有Activity销毁自动回收的机制开发时要留意内存泄漏。习题5【概念简答题】大型项目多模块拆分的时候为什么跨模块路由会比较麻烦答案业务模块之间互相隔离A业务模块不能直接引用B模块内部页面Compose函数需要通过路由字符串注册不能直接硬编码页面函数调用需要统一维护路由表。解读因此很多大型多模块项目会引入专门的组件化路由框架。本节课知识点总结单Activity架构整个App只有一个MainActivity全部业务页面依靠Navigation‑Compose管理回退栈减少Activity切换开销。中小型项目app模块内部分包ui / viewmodel / repository / data够用不必拆分多module。common基础library模块存放通用组件、工具、扩展禁止写上层业务依赖单向。模块化适合大型项目可以多人并行开发、增量编译但是Gradle配置、跨模块路由复杂度上升小项目不要盲目拆分。模块之间严格单向依赖禁止循环依赖。下一课预告进阶第13课Compose状态总结复习整套系列综合小项目实战简易笔记App
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进