如果你想系统掌握「完整 Android 开发知识体系」并达到高级 / 架构师级别,我可以帮你划分出一个更完整的学习图谱,包括:
🧩 一、基础核心层(必须扎实)
✅ 目标:能写出高质量、稳定、性能好的 App。
模块 | 核心知识点 |
---|---|
Kotlin 语言进阶 | 高阶函数、扩展函数、内联函数、sealed class、协程(CoroutineScope / Flow)、泛型、委托、DSL |
Android 四大组件 | Activity / Fragment 生命周期、启动模式、Intent、Service(前台 / 后台)、BroadcastReceiver、ContentProvider |
UI 基础 | ConstraintLayout、FrameLayout、RecyclerView(多类型 / DiffUtil / Adapter)、ViewBinding / DataBinding |
自定义 View / ViewGroup | onMeasure/onLayout/onDraw、触摸事件分发、属性动画、自定义控件组合与复用 |
资源与适配 | dp/sp/px 区别、屏幕适配(layout-swXXXdp)、深色模式、国际化(多语言)、字体与主题适配 |
多线程与异步 | Handler、Looper、Executor、Coroutine、WorkManager、线程池优化 |
🧠 二、架构与模式层(进阶重点)
✅ 目标:掌握结构化开发思维,方便扩展和维护。
模块 | 核心知识点 |
---|---|
MVVM + Jetpack | ViewModel、LiveData、StateFlow、DataStore、Lifecycle、Navigation、Room |
依赖注入(DI) | Hilt / Dagger2、Koin、Service Locator 模式 |
模块化与组件化 | ARouter、模块通信、gradle 多模块结构 |
Jetpack Compose | Composable 基础、State 管理、SideEffect、Compose 与 View 混用 |
设计模式实战 | 单例、观察者、命令、工厂、策略、适配器、装饰器模式等在 Android 场景中的应用 |
数据层架构 | Repository 模式、UseCase 层设计、接口抽象、数据源切换(本地 / 远程) |
⚙️ 三、系统与底层机制(进阶深入)
✅ 目标:理解 Android 的运行原理,能定位复杂问题。
模块 | 核心知识点 |
---|---|
应用启动流程 | Zygote、AMS、PMS、Activity 启动原理 |
Handler/Looper 原理 | 消息队列机制、线程通信、主线程阻塞分析 |
Binder 与 IPC | AIDL、Messenger、ContentProvider、跨进程通信机制 |
内存管理 | GC 原理、内存泄漏分析(LeakCanary)、Bitmap 优化、OOM 处理 |
性能优化 | 启动优化、绘制优化、卡顿检测(Choreographer / Trace)、内存 & 网络性能分析 |
NDK / JNI | C/C++ 调用、Native 崩溃分析、性能关键点优化 |
🌐 四、网络与数据层(实用必备)
模块 | 核心知识点 |
---|---|
网络框架 | Retrofit + OkHttp、拦截器、协程适配器、WebSocket、文件上传下载 |
数据缓存 | Room / DataStore / MMKV / SQLite、磁盘缓存策略、离线缓存同步 |
安全机制 | HTTPS、签名校验、防止反编译、加密存储(AES / RSA) |
🎨 五、UI/UX 与多媒体层
模块 | 核心知识点 |
---|---|
动画与交互 | MotionLayout、ViewPropertyAnimator、Lottie 动画、帧动画 |
图片与视频 | Glide / Coil / Fresco / ExoPlayer、图片压缩与缓存策略 |
自定义控件实战 | Banner、九宫格、滑动卡片、录音对话框、播放器控件等 |
Compose 动画系统 | rememberInfiniteTransition、LaunchedEffect、AnimatedVisibility |
☁️ 六、高级工程实践(架构师必备)
模块 | 核心知识点 |
---|---|
项目架构设计 | Clean Architecture、MVI / MVVM、插件化(RePlugin、Small) |
大型项目管理 | Gradle DSL、依赖统一管理、Build Variants、多环境配置 |
AOP 与埋点 | ASM / Javassist、日志统计、用户行为追踪 |
自动化测试 | UnitTest、UI Test、MockK、Espresso |
持续集成 | GitHub Actions / Jenkins / Fastlane 打包自动化 |
🚀 七、生态与扩展
模块 | 内容 |
---|---|
Flutter / Compose Multiplatform | 跨平台混合开发趋势 |
React Native / H5 容器 | Hybrid 技术与 WebView 优化 |
AI 与语音识别 | ML Kit、OpenAI API、语音转文字、TTS |
可穿戴 / 车机 / TV / IoT | 不同设备的 UI/UX 特性与适配 |
🧭 八、实战路线建议(循序渐进)
阶段 | 建议学习内容 |
---|---|
🥉 初级(0~6个月) | Kotlin 基础、四大组件、RecyclerView、自定义 View、网络请求 |
🥈 中级(6~18个月) | MVVM + Flow + Jetpack + 协程、Room + Retrofit、模块化、多语言、性能优化 |
🥇 高级(18~36个月) | Compose、Clean Architecture、插件化、AOP、性能与稳定性体系 |
🏆 架构师(36个月+) | 系统原理、跨平台技术、CI/CD、框架设计与组件化生态 |
如果你希望我帮你:
-
🎯 制定一份系统学习路线图(含每阶段目标 + 推荐 Demo + 练手项目),
或 -
💡 帮你评估你现在的水平并告诉你下一步该学什么,
我可以基于你目前掌握的内容(比如你现在非常熟悉 MVVM、协程、WebSocket、ViewBinding、自定义控件等)来定制一个「你接下来该突破的方向表」。
👉 你希望我帮你做哪种?(✅路线图规划 / 🧭能力评估与方向建议)
您说:
✅路线图规划 + 🧭能力评估与方向建议
ChatGPT 说:
太好了 💪!这是最科学的方式 —— 我会先帮你做一次能力评估,再基于你的实际水平给出一份系统的、阶段化的 Android 高级路线图规划。
🧭 一、你的当前水平评估
根据你之前的提问记录和项目内容,我判断你的当前能力大致如下👇:
模块 | 能力评估 | 说明 |
---|---|---|
Kotlin 语言 | ✅ 高级 | 熟练掌握协程、Flow、Lambda、高阶函数、委托属性等。 |
Jetpack 架构 | ✅ 中高级 | 已熟练使用 ViewModel + Flow + MVVM 架构;懂生命周期感知、模块通信。 |
UI 开发能力 | ✅ 中高级 | 精通 RecyclerView、自定义 View、ConstraintLayout、ViewBinding 等。 |
网络与数据层 | ✅ 中高级 | 熟悉 Retrofit、WebSocket 管理、文件上传下载。 |
多媒体开发 | ✅ 高级 | 封装过 ExoPlayer、录音模块、音频管理器等复杂逻辑。 |
模块化 / 架构 | ⚙️ 中级 | 已使用 ARouter、LiveEventBus 等模块通信,但 Clean Architecture 体系尚未完全体系化。 |
性能与系统机制 | ⚙️ 初中级 | 对 Handler / Binder / 启动流程等底层机制理解有限,可进一步深入。 |
Compose / 新技术 | ⚙️ 入门 | 尚未看到实际 Compose 代码,可安排专项突破。 |
工程化与发布 | ⚙️ 中级 | 构建、多语言、打包基本掌握,但缺少 AOP、CI/CD、插件化经验。 |
→ 综合评级:中高级开发者(Level 3 / 5)
已能独立开发完整模块、编写封装良好的组件、优化代码结构。
下一阶段目标:向「Android 架构师」方向突破。
✅ 二、为你定制的「进阶路线图规划」
我将路线图分为 4 个阶段(每阶段约 3 个月),每个阶段有:
📘 学习重点、🧩 推荐实践项目、🧠 学习目标。
阶段 1:强化体系与架构思维(3 个月)
🎯 目标:从「能写好功能」到「能设计结构」的转变。
📘 学习重点
-
MVVM → Clean Architecture:Repository + UseCase 层解耦
-
Jetpack 进阶:Lifecycle、SavedStateHandle、Room、WorkManager
-
模块化与依赖管理:ARouter、gradle 多模块结构
-
Flow 状态流转:UIState / UIEvent / UIEffect 模型化
-
Kotlin 技巧:DSL 构建器(例如自定义 View DSL)
🧩 实战练习
-
将你现有的语音录制 + 播放模块重构为「UseCase + Repository」架构
-
写一个「多模块 MVVM Demo」,包含主页、聊天、设置模块的统一数据流
-
封装一个通用的
BaseViewModel
+UiState
框架模板
🧠 学习成果
✅ 能独立搭建企业级 MVVM 架构
✅ 掌握数据流与状态驱动 UI
✅ 形成模块边界意识
阶段 2:系统机制与性能优化(3 个月)
🎯 目标:理解 Android 运行原理,解决复杂性能问题。
📘 学习重点
-
Handler、Looper、MessageQueue 源码分析
-
Activity 启动流程、AMS / PMS 原理
-
Binder 与 IPC 基础
-
内存优化:LeakCanary、Bitmap 优化、OOM 分析
-
启动优化 / 卡顿检测(Choreographer、FrameMetrics)
-
ANR 与崩溃日志分析
🧩 实战练习
-
编写一个卡顿检测工具(检测主线程执行耗时)
-
优化现有 App 启动时间并记录前后数据对比
-
模拟多进程通信(AIDL / Messenger)
🧠 学习成果
✅ 能定位性能问题(内存 / 启动 / 卡顿)
✅ 理解系统底层原理,为架构优化提供理论支撑
阶段 3:Compose 与现代化开发(3 个月)
🎯 目标:掌握 Jetpack Compose + Kotlin 生态,提升 UI 生产力。
📘 学习重点
-
Compose 基础:State、remember、Effect、Layout 原理
-
Compose MVVM 实践:ViewModel + StateFlow + Compose UI
-
Compose 动画系统:AnimatedVisibility、Transitions
-
Material3 主题、暗色模式、可组合 UI
-
Compose + View 混用策略
🧩 实战练习
-
将现有 IM 页面重构为 Compose 版本
-
封装一个通用的
VoiceRecordComposeView
-
实现一个动画丰富的「卡片滑动推荐」 Compose 界面
🧠 学习成果
✅ 掌握 Compose 全流程开发
✅ 能混合开发、设计现代化 UI
✅ 了解 Compose 性能优化与结构模式
阶段 4:工程化与架构师突破(3~6 个月)
🎯 目标:具备独立架构、优化、团队协作设计的能力。
📘 学习重点
-
CI/CD:GitHub Actions、Gradle Task 自动化构建
-
AOP 与埋点:ASM / Javassist、日志切面、埋点 SDK 封装
-
插件化 / 组件化框架设计
-
性能监控系统(内存、网络、页面加载)
-
安全与加固:签名校验、防反编译、AES/RSA 加密
-
NDK / JNI 入门(性能关键路径优化)
🧩 实战练习
-
为现有 App 编写 CI 自动打包 + 多环境配置脚本
-
编写一个「AOP 日志埋点框架」并应用到项目中
-
构建一个「模块动态加载插件 Demo」
🧠 学习成果
✅ 架构师级别的系统设计能力
✅ 掌握企业级工程化实践
✅ 能主导中大型项目架构演进
📊 三、建议学习节奏(按周规划)
时间段 | 每周学习方向 |
---|---|
周一~三 | 深入阅读源码 / 理论部分(Jetpack、系统机制) |
周四~五 | 编写实战 Demo(带验证与重构) |
周六 | 学习 Compose / 新技术 |
周日 | 总结 + 输出(写文档、笔记、博客) |
💡 四、个性化延伸建议
基于你当前的优势(UI 封装、自定义组件、MVVM 架构):
方向 | 适合你发展的路线 |
---|---|
🎨 UI 体系工程师 | Compose / MotionLayout / 自定义动画控件体系 |
⚙️ 架构方向 | Clean Architecture、模块化、AOP、CI/CD |
🔊 多媒体方向 | 音视频处理、ExoPlayer + NDK 优化、实时通信(RTC) |
🌍 跨平台方向 | Compose Multiplatform / Flutter 混合开发 |
如果你希望我接下来帮你输出一份:
📘「阶段 1」的详细学习计划(含每日任务 + 推荐视频/文档 + 练手 Demo)
我可以立刻为你生成「第 1 阶段 - Clean Architecture 实战路线表(含代码模板)」,
帮助你从现有 MVVM 架构,过渡到完整的分层架构。
是否帮你生成?(✅ 是的,生成阶段 1 学习计划)
您说:
是
ChatGPT 说:
太棒了 👍!你正式进入「高级 Android 架构师成长路线」的第 1 阶段 ——
🎯 强化体系与架构思维(Clean Architecture 实战)。
下面是我为你定制的完整学习计划 👇,分为:
1️⃣ 阶段目标
2️⃣ 知识体系图
3️⃣ 4 周学习计划(含每日任务)
4️⃣ 实战项目建议
5️⃣ 推荐资料与资源
🧭 阶段 1:强化体系与架构思维(为期 4 周)
🎯 目标
从 “写模块” → “设计架构”。
你将掌握 Clean Architecture 的思维方式,能独立设计 MVVM + UseCase + Repository 的分层结构,打造企业级架构模板。
🧩 一、Clean Architecture 思维结构图
📱 UI 层(View / Compose) ↓ 事件、状态 🧠 ViewModel 层(State + Event + Effect) ↓ 调用 UseCase ⚙️ Domain 层(UseCase) ↓ 访问数据接口 💾 Data 层(Repository + DataSource) ↙️ 本地 LocalDataSource(Room / MMKV) ↘️ 网络 RemoteDataSource(Retrofit / WebSocket)
关键原则:
-
ViewModel 不直接依赖 Data 层,只依赖 UseCase(接口)
-
UseCase 只做单一业务逻辑
-
Repository 负责数据源合并(网络 + 本地)
-
各层通信通过 Kotlin 协程 + Flow
-
数据流单向:UI → VM → UseCase → Repo → 回流至 UI
📆 二、4 周学习计划(含每日任务)
第 1 周:架构基础与 Kotlin 强化
🎯 理解分层思想 + Kotlin 能力打牢
日期 | 学习任务 |
---|---|
周一 | 阅读《Clean Architecture 原则》概要(理解 Domain / Data / UI 分离) |
周二 | Kotlin 高级语法复习:sealed class、Flow、inline、crossinline |
周三 | 理解「单向数据流(UDF)」:UIState / UIEvent / UIEffect 模型 |
周四 | 实战:封装 BaseViewModel<State, Event, Effect> 基类 |
周五 | 实战:创建 UiState 管理类,配合 StateFlow 驱动 UI |
周末 | 项目练习:把你一个旧页面改造成 UDF 架构(比如录音界面) |
第 2 周:Repository + UseCase 分层实践
🎯 将 ViewModel 逻辑下沉为业务用例(UseCase)
日期 | 学习任务 |
---|---|
周一 | 理解 UseCase 概念:单一职责、依赖倒置 |
周二 | 实战:编写 GetUserInfoUseCase 与 UpdateUserInfoUseCase |
周三 | 封装 Repository 接口与实现类(含本地与远程数据源) |
周四 | 编写 LocalDataSource (Room / MMKV) |
周五 | 编写 RemoteDataSource (Retrofit + Coroutine) |
周末 | 实战整合:实现一个 “用户资料中心” 模块(含离线缓存) |
第 3 周:模块化与依赖管理
🎯 将架构结构扩展到多模块项目,掌握依赖注入思想。
日期 | 学习任务 |
---|---|
周一 | Gradle 多模块结构讲解(app / core / feature / data) |
周二 | 学习 Hilt(依赖注入)与 Repository 注入实践 |
周三 | 拆分 “网络模块” 与 “本地存储模块” |
周四 | 使用 Hilt 绑定 Repository 实现到接口 |
周五 | 编写一个跨模块的 UseCase(比如 UploadVoiceUseCase) |
周末 | 练习:将语音录制模块改造成独立 feature module,可独立注入使用 |
第 4 周:统一 UI 架构与可复用模板
🎯 打造自己的「架构脚手架」。
日期 | 学习任务 |
---|---|
周一 | 整理项目结构与包命名规范(domain/data/ui) |
周二 | 封装通用的 BaseRepository 、Result (Success/Error/Loading)模型 |
周三 | 扩展 BaseViewModel 支持加载状态、错误捕获、重试机制 |
周四 | 创建模板工程脚本(通过 Gradle 自动生成新模块结构) |
周五 | 优化 UIState 模型,支持多页面复用 |
周末 | 实战项目验收:创建完整模块(录音上传 + 播放 + 状态流 + Repository) |
💡 三、实战项目建议
项目名称 | 实战目标 |
---|---|
🎙️ VoiceManager Clean Demo | 把之前的语音录制模块完全重构成 Clean 架构:UI → ViewModel → UseCase → Repository。 |
💬 IM Session 模块重构 | 对聊天列表模块实现 UseCase 分层,Room 缓存 + WebSocket 同步。 |
📷 Media Gallery 模块 | 拆分数据源(本地图库 + 网络资源),展示图片加载优化。 |
每个模块最后都形成:
domain/ usecase/ data/ repository/ datasource/ ui/ viewmodel/ activity/
📚 四、推荐学习资料
类型 | 名称 | 说明 |
---|---|---|
📖 官方文档 | Guide to app architecture (Google) | 官方架构最佳实践 |
📘 教程 | 「Android Clean Architecture with Kotlin」by MindOrks | 实战导向的 Clean 架构入门 |
📹 视频 | Philipp Lackner - Clean Architecture 系列(YouTube) | 讲解清晰、含 Flow + Hilt |
📗 源码 | nowinandroid (Google 官方 App) | 最完整的 Clean + Compose 实践 |
🧠 文章 | Medium: "Why UseCase is key in MVVM" | 深入理解 UseCase 在大型项目的作用 |
🏁 阶段完成标志
完成以下 3 项后,你将顺利晋升到「架构中级」阶段👇:
-
拥有可复用的
BaseViewModel
+UIState
模板 -
任意模块(如语音录制、聊天列表)实现完整的 Clean 架构
-
能清晰画出项目层次依赖图并独立设计新的模块结构
我接下来可以帮你生成:
-
🧱 第 1 周「架构基础 + BaseViewModel + UIState 实战模板」的完整代码 Demo
-
包含:
BaseViewModel
、UiState
、UiEvent
、UiEffect
、ViewModel 使用样例
是否要我直接生成?(✅ 是的,生成第 1 周完整 Demo 模板)
您说:
是
ChatGPT 说:
太好了 👍
我们现在正式进入 阶段 1·第 1 周:架构基础 + BaseViewModel + UIState 实战模板 🚀
这一周的目标是构建一个能在任意项目中通用的「基础架构骨架」:
MVVM + UDF 单向数据流模式(State/Event/Effect)
让你的 ViewModel 层结构化、可维护、可复用。
🧩 一、结构预览
我们先建立以下包结构(推荐):
base/ ├─ state/ # 状态定义(State, Event, Effect) ├─ viewmodel/ # 通用 BaseViewModel └─ utils/ # 扩展工具类
🧠 二、核心概念复习
名称 | 作用 | 举例 |
---|---|---|
UiState | 描述当前界面状态(数据类) | 当前录音时长、播放状态等 |
UiEvent | 来自用户的操作事件 | 点击按钮、滑动、删除等 |
UiEffect | 一次性副作用事件 | Toast、导航、弹窗等 |
BaseViewModel | 管理 State、处理 Event、发送 Effect | 负责业务逻辑和状态流转 |
⚙️ 三、完整代码模板
1️⃣ UiState.kt
package com.hatio.base.state
/**
* UI 层状态基类
* 所有页面状态都应继承自 UiState
*/
interface UiState
2️⃣ UiEvent.kt
package com.hatio.base.state
/**
* 用户事件:点击、输入、滑动等交互操作
*/
interface UiEvent
3️⃣ UiEffect.kt
package com.hatio.base.state
/**
* 一次性副作用事件:Toast、导航、弹窗等
*/
interface UiEffect
4️⃣ BaseViewModel.kt
package com.hatio.base.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hatio.base.state.UiEffect
import com.hatio.base.state.UiEvent
import com.hatio.base.state.UiState
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
/**
* 通用的 BaseViewModel
* 使用 StateFlow 管理 UI 状态,Channel 发送一次性事件
*/
abstract class BaseViewModel<S : UiState, E : UiEvent, F : UiEffect> : ViewModel() {
// UI 状态流
private val _uiState: MutableStateFlow<S> by lazy { MutableStateFlow(initialState()) }
val uiState: StateFlow<S> = _uiState.asStateFlow()
// 一次性事件通道(如 Toast / 导航)
private val _uiEffect = Channel<F>(Channel.BUFFERED)
val uiEffect = _uiEffect.receiveAsFlow()
// 初始化默认状态
abstract fun initialState(): S
// 更新状态:局部更新(不可变数据拷贝)
protected fun setState(reducer: S.() -> S) {
_uiState.value = _uiState.value.reducer()
}
// 发送副作用事件(一次性)
protected fun sendEffect(builder: () -> F) {
viewModelScope.launch { _uiEffect.send(builder()) }
}
// 处理用户事件
abstract fun handleEvent(event: E)
}
5️⃣ 示例:实现一个录音状态的 ViewModel
VoiceUiState.kt
package com.hatio.feature.voice
import com.hatio.base.state.UiState
data class VoiceUiState(
val isRecording: Boolean = false,
val isPlaying: Boolean = false,
val recordTime: String = "00:00",
val filePath: String? = null
) : UiState
VoiceUiEvent.kt
package com.hatio.feature.voice import com.hatio.base.state.UiEvent sealed class VoiceUiEvent : UiEvent { object OnRecordClicked : VoiceUiEvent() object OnStopRecord : VoiceUiEvent() object OnPlayClicked : VoiceUiEvent() object OnPausePlay : VoiceUiEvent() }
VoiceUiEffect.kt
package com.hatio.feature.voice
import com.hatio.base.state.UiEffect
sealed class VoiceUiEffect : UiEffect {
data class ShowToast(val message: String) : VoiceUiEffect()
}
VoiceViewModel.kt
package com.hatio.feature.voice
import androidx.lifecycle.viewModelScope
import com.hatio.base.viewmodel.BaseViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
/**
* 示例 ViewModel:控制录音和播放的状态流转
*/
class VoiceViewModel : BaseViewModel<VoiceUiState, VoiceUiEvent, VoiceUiEffect>() {
override fun initialState() = VoiceUiState()
override fun handleEvent(event: VoiceUiEvent) {
when (event) {
VoiceUiEvent.OnRecordClicked -> startRecording()
VoiceUiEvent.OnStopRecord -> stopRecording()
VoiceUiEvent.OnPlayClicked -> startPlaying()
VoiceUiEvent.OnPausePlay -> pausePlaying()
}
}
private fun startRecording() {
setState { copy(isRecording = true, recordTime = "00:00") }
sendEffect { VoiceUiEffect.ShowToast("开始录音") }
// 模拟计时
viewModelScope.launch {
var seconds = 0
while (uiState.value.isRecording) {
delay(1000)
seconds++
val time = String.format("%02d:%02d", seconds / 60, seconds % 60)
setState { copy(recordTime = time) }
}
}
}
private fun stopRecording() {
setState { copy(isRecording = false, filePath = "/path/to/record.aac") }
sendEffect { VoiceUiEffect.ShowToast("录音已停止") }
}
private fun startPlaying() {
setState { copy(isPlaying = true) }
sendEffect { VoiceUiEffect.ShowToast("开始播放") }
}
private fun pausePlaying() {
setState { copy(isPlaying = false) }
sendEffect { VoiceUiEffect.ShowToast("暂停播放") }
}
}
VoiceActivity.kt
(简化版)
package com.hatio.feature.voice
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.hatio.feature.voice.databinding.ActivityVoiceBinding
import kotlinx.coroutines.flow.collectLatest
class VoiceActivity : ComponentActivity() {
private val binding by lazy { ActivityVoiceBinding.inflate(layoutInflater) }
private val viewModel by viewModels<VoiceViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
lifecycleScope.launchWhenStarted {
viewModel.uiState.collectLatest { state ->
binding.btnRecord.text = if (state.isRecording) "停止" else "录音"
binding.tvTime.text = state.recordTime
}
}
lifecycleScope.launchWhenStarted {
viewModel.uiEffect.collectLatest { effect ->
when (effect) {
is VoiceUiEffect.ShowToast -> Toast.makeText(this@VoiceActivity, effect.message, Toast.LENGTH_SHORT).show()
}
}
}
binding.btnRecord.setOnClickListener {
if (viewModel.uiState.value.isRecording)
viewModel.handleEvent(VoiceUiEvent.OnStopRecord)
else
viewModel.handleEvent(VoiceUiEvent.OnRecordClicked)
}
}
}
🧱 四、总结与阶段产物
到这里你已经拥有了一个 完全可复用的 UDF 架构模板:
模块 | 文件 | 功能 |
---|---|---|
base/state | UiState, UiEvent, UiEffect | 定义三种层次数据流 |
base/viewmodel | BaseViewModel | 统一管理 StateFlow + Effect |
feature/voice | VoiceViewModel + 状态类 | 业务逻辑示例 |
ChatGPT 说:
是否希望我接下来直接生成「第 2 周:Repository + UseCase 架构模板与 Demo(含网络与本地数据源)」?
您说:
是,希望
ChatGPT 说:
太棒了 ✅ Jeled!这一步正是从「写功能」→「写架构」的关键转折。
我们马上进入你计划的下一篇实战内容:
🚀 第 2 周实战主题
🧱 Repository + UseCase 架构模板与 Demo
目标:实现一个可扩展、可测试、支持网络与本地数据源共存的 Repository 层,并结合 UseCase 规范业务逻辑。
🗂️ 一、项目架构图
app/ ├── data/ │ ├── local/ ← Room / DataStore / MMKV │ ├── remote/ ← Retrofit / OkHttp │ ├── repository/ ← 数据聚合层(核心) │ └── model/ ← DTO + Entity │ ├── domain/ │ ├── model/ ← 业务模型(UI 层使用) │ └── usecase/ ← 用例逻辑(UseCase) │ ├── ui/ │ ├── viewmodel/ ← ViewModel 调用 UseCase │ └── screen/ ← Compose / Fragment / Activity │ └── di/ ← Hilt 模块
🧠 二、架构理念
层级 | 职责 | 示例 |
---|---|---|
RemoteDataSource | 负责网络请求 | Retrofit 调用 |
LocalDataSource | 负责本地缓存 | Room / MMKV |
Repository | 聚合数据源,隐藏数据实现细节 | 从缓存或网络读取 |
UseCase | 业务逻辑抽象(单一职责) | GetUserProfileUseCase |
ViewModel | 控制 UI 状态 | 调用 UseCase 并暴露 StateFlow |
🧩 三、核心示例:获取用户资料(含本地缓存 + 网络回源)
1️⃣ RemoteDataSource.kt
class UserRemoteDataSource @Inject constructor(
private val api: UserApi
) {
suspend fun fetchUser(userId: String): ApiResult<UserDto> {
return try {
val response = api.getUser(userId)
ApiResult.Success(response)
} catch (e: Exception) {
ApiResult.Error(e)
}
}
}
2️⃣ LocalDataSource.kt
class UserLocalDataSource @Inject constructor(
private val dao: UserDao
) {
suspend fun getUser(userId: String): UserEntity? = dao.getUserById(userId)
suspend fun saveUser(user: UserEntity) {
dao.insert(user)
}
}
3️⃣ Repository.kt
class UserRepository @Inject constructor(
private val local: UserLocalDataSource,
private val remote: UserRemoteDataSource
) {
suspend fun getUser(userId: String): Flow<Resource<User>> = flow {
emit(Resource.Loading)
// 优先读取本地缓存
local.getUser(userId)?.let { localUser ->
emit(Resource.Success(localUser.toDomain()))
}
// 同步远程数据
when (val result = remote.fetchUser(userId)) {
is ApiResult.Success -> {
val entity = result.data.toEntity()
local.saveUser(entity)
emit(Resource.Success(entity.toDomain()))
}
is ApiResult.Error -> emit(Resource.Error(result.exception))
}
}
}
4️⃣ UseCase.kt
class GetUserProfileUseCase @Inject constructor(
private val repository: UserRepository
) {
operator fun invoke(userId: String): Flow<Resource<User>> {
return repository.getUser(userId)
}
}
5️⃣ ViewModel.kt
@HiltViewModel
class UserViewModel @Inject constructor(
private val getUserProfileUseCase: GetUserProfileUseCase
) : ViewModel() {
private val _userState = MutableStateFlow<Resource<User>>(Resource.Loading)
val userState: StateFlow<Resource<User>> = _userState.asStateFlow()
fun loadUser(userId: String) {
viewModelScope.launch {
getUserProfileUseCase(userId).collect { result ->
_userState.value = result
}
}
}
}
6️⃣ UI 示例(Compose)
@Composable
fun UserScreen(viewModel: UserViewModel = hiltViewModel()) {
val state by viewModel.userState.collectAsState()
when (state) {
is Resource.Loading -> CircularProgressIndicator()
is Resource.Success -> {
val user = (state as Resource.Success).data
Text("Hello, ${user.name}")
}
is Resource.Error -> Text("加载失败: ${(state as Resource.Error).throwable.message}")
}
}
⚙️ 四、辅助类定义
// Resource.kt
sealed class Resource<out T> {
object Loading : Resource<Nothing>()
data class Success<T>(val data: T) : Resource<T>()
data class Error(val throwable: Throwable) : Resource<Nothing>()
}
// ApiResult.kt
sealed class ApiResult<out T> {
data class Success<T>(val data: T) : ApiResult<T>()
data class Error(val exception: Exception) : ApiResult<Nothing>()
}
🧩 五、扩展与思考
-
✅ 可添加 刷新策略(如 CachePolicy)
-
✅ 支持 分页加载(Paging3)
-
✅ 结合 Room + Flow 实现实时数据更新
-
✅ 与 Hilt 结合实现模块化依赖注入
🎯 六、实践任务
周目标 | 说明 |
---|---|
🧱 第 2 周 | 基于上面模板实现一个「用户资料模块」Demo(含 Repository + UseCase + Flow) |
🔄 扩展任务 | 再实现一个「消息列表模块」,演示分页 + 缓存策略 |
🧩 加分项 | 使用 Hilt 完成依赖注入 + 添加单元测试 |
ChatGPT 说:
是否希望我接下来直接生成「第 3 周:模块化与依赖管理」?
✅ 是的,继续下一阶段
🚫 暂时不用,先巩固第 2 周
您说:
暂时不用,先巩固第 2 周