Jetpack Compose 协程Coroutine完整实战教程现代 Android 开发里Compose 协程 Flow已经是官方主流架构。如果你只会Button(onClick{})但不会LaunchedEffectrememberCoroutineScopeStateFlowcollectAsStateCompose 生命周期协程那基本还没进入真正的 Compose 开发。这一篇从原理 → 生命周期 → 实战 → 架构完整讲透。一、为什么 Compose 特别依赖协程因为Compose 是声明式 UIUI 本身状态变化 → 自动刷新而协程非常适合异步请求状态更新Flow 数据流UI 生命周期所以Compose 和协程天然契合。二、Compose 中最重要的协程 APIAPI作用LaunchedEffect页面生命周期协程rememberCoroutineScope手动启动协程collectAsState收集 FlowproduceState协程转 StatesnapshotFlowState 转 Flow三、LaunchedEffect最核心这是 Compose 协程第一核心。四、第一个 LaunchedEffectComposablefunTestPage(){LaunchedEffect(Unit){delay(2000)println(执行)}}它是什么本质Compose 生命周期协程当 Composable 进入界面自动启动协程离开界面自动取消协程五、为什么不能直接 launch很多新人这样写ComposablefunTest(){GlobalScope.launch{// ...}}这是错误的。因为Composable 会频繁重组Recompose可能疯狂创建协程导致内存泄漏、重复请求、协程爆炸六、LaunchedEffect 生命周期阶段行为进入 Composition启动协程离开 Composition取消协程key 改变重新启动协程七、key 的作用非常重要LaunchedEffect(userId){loadUser(userId)}当userId变化时取消旧协程启动新协程八、LaunchedEffect(Unit)最常见。LaunchedEffect(Unit)表示仅首次进入执行一次类似Activity.onCreate()九、Compose 倒计时ComposablefunCountDown(){vartimebyremember{mutableStateOf(10)}LaunchedEffect(Unit){while(time0){delay(1000)time--}}Text($time)}为什么 UI 自动刷新因为mutableStateOf状态变化后Compose 自动重组 UI。十、rememberCoroutineScope第二核心。十一、为什么需要它因为Button点击时不能直接调用 suspend错误Button(onClick{delay(1000)// onClick 不是 suspend})十二、正确写法ComposablefunTest(){valscoperememberCoroutineScope()Button(onClick{scope.launch{delay(1000)println(点击)}}){Text(按钮)}}十三、rememberCoroutineScope 本质它返回与当前 Composition 绑定的 CoroutineScope页面销毁自动 cancel。十四、LaunchedEffect vs rememberCoroutineScope这是高频面试题。LaunchedEffectrememberCoroutineScope适合自动执行任务适合用户事件触发页面初始化Button 点击自动请求手势事件倒计时SnackbarFlow 收集十五、Compose ViewModel现代 Android 标准方案。ViewModelclassUserViewModel:ViewModel(){varuserbymutableStateOfUser?(null)privatesetfunloadUser(){viewModelScope.launch{userapi.getUser()}}}ComposeComposablefunUserPage(vm:UserViewModelviewModel()){LaunchedEffect(Unit){vm.loadUser()}Text(vm.user?.name?:)}为什么不用 lifecycleScopeCompose 推荐ViewModelScopeUI 只负责显示状态十六、Compose StateFlow现代官方方案这是最重要的。ViewModelclassUserViewModel:ViewModel(){privateval_uiStateMutableStateFlowUser?(null)valuiState_uiState.asStateFlow()funload(){viewModelScope.launch{_uiState.valueapi.getUser()}}}Compose 收集 FlowComposablefunUserPage(vm:UserViewModelviewModel()){valuserbyvm.uiState.collectAsState()Text(user?.name?:)}十七、collectAsState 本质它将Flow → Compose State当 Flow 发射新数据自动重组 UI。十八、完整执行流程最重要ViewModelScope ↓ 网络请求 ↓ StateFlow更新 ↓ collectAsState收到 ↓ Compose自动重组 ↓ UI刷新这就是现代 Android UI 响应式架构十九、Compose Retrofit 协程完整现代写法。RepositoryclassUserRepository{suspendfungetUser()api.getUser()}ViewModelclassUserViewModel:ViewModel(){privatevalrepositoryUserRepository()varuserbymutableStateOfUser?(null)privatesetfunloadUser(){viewModelScope.launch{userrepository.getUser()}}}Compose UIComposablefunUserScreen(vm:UserViewModelviewModel()){LaunchedEffect(Unit){vm.loadUser()}Text(vm.user?.name?:)}二十、为什么不在 Compose 直接请求网络错误LaunchedEffect(Unit){api.getUser()}因为UI 不应该直接操作数据层否则不好测试、生命周期混乱、逻辑耦合。二十一、Compose 中的协程取消Compose 生命周期结束自动 cancel。例如LaunchedEffect离开页面协程自动结束。二十二、rememberUpdatedState高级经典问题LaunchedEffect 内拿到旧值。vallatestCallbackbyrememberUpdatedState(onClick)作用始终拿到最新 lambda避免闭包旧引用问题。二十三、produceState作用协程 → StatevaluserbyproduceStateUser?(null){valueapi.getUser()}本质内部其实就是LaunchedEffect mutableStateOf二十四、snapshotFlow作用Compose State → FlowsnapshotFlow{text}.collect{// ...}适合搜索监听、输入变化、滚动监听。二十五、Compose 搜索防抖经典实战ViewModelclassSearchViewModel:ViewModel(){valkeywordMutableStateFlow()init{viewModelScope.launch{keyword.debounce(500).collect{search(it)}}}}ComposeTextField(valuetext,onValueChange{textit vm.keyword.valueit})二十六、Snackbar 协程这是rememberCoroutineScope高频场景。valsnackbarHostStateremember{SnackbarHostState()}valscoperememberCoroutineScope()Button(onClick{scope.launch{snackbarHostState.showSnackbar(成功)}}){}二十七、Compose 动画为什么也用协程Compose 动画很多本质也是 suspend。例如Animatable.animateTo()内部协程驱动帧刷新二十八、Compose 中常见错误错误说明在 Composable 直接GlobalScope.launch生命周期不可控重组导致重复请求api.getUser()直接写在 UIcollect没有生命周期flow.collect可能泄漏二十九、正确的 Flow 收集推荐collectAsState()或者collectAsStateWithLifecycle()官方推荐三十、collectAsStateWithLifecycleimplementationandroidx.lifecycle:lifecycle-runtime-composevaluiStatebyvm.uiState.collectAsStateWithLifecycle()为什么推荐它自动处理生命周期页面不可见自动暂停收集。三十一、Compose Room Flow现代数据库方案。DAOQuery(SELECT * FROM user)fungetUsers():FlowListUserComposevalusersbydao.getUsers().collectAsState(initialemptyList())数据库变化UI 自动刷新。三十二、Compose Paging3 协程现代列表方案。ViewModelPager(...).flow.cachedIn(viewModelScope)ComposecollectAsLazyPagingItems()三十三、Compose 协程源码核心最核心RecomposerCoroutineScopeMonotonicFrameClockCompose 本质也是协程驱动。三十四、Compose 为什么不卡 UI因为suspend不阻塞线程Recomposer分帧执行状态驱动刷新三十五、Compose 协程面试题1. LaunchedEffect 和 rememberCoroutineScope 区别API用途LaunchedEffect自动生命周期任务rememberCoroutineScope用户事件协程2. collectAsState 本质Flow → State3. Compose 为什么容易重复请求因为重组Recomposition4. 为什么不用 GlobalScope因为生命周期不可控5. Compose 官方推荐状态方案StateFlowcollectAsStateWithLifecycle三十六、现代 Compose 最佳架构企业级Compose UI ↓ ViewModel ↓ StateFlow ↓ Repository ↓ Retrofit / Room三十七、真正理解 Compose 协程Compose 真正核心UI State 的函数而协程负责异步修改 State最终State变化 → Compose自动重组 → UI自动刷新这就是现代 Android 的本质。三十八、真正的大脑模型最重要看到LaunchedEffect自动想到Composition生命周期 CoroutineScope 自动取消看到collectAsState()自动想到Flow → State → Recomposition看到viewModelScope.launch自动想到协程 → 更新StateFlow → Compose刷新UI三十九、最后一句Compose 为什么这么强传统 AndroidCompose手动找View状态驱动UI手动刷新UI协程驱动异步手动管理生命周期Flow驱动数据流这就是Google 现在整个 Android UI 架构的核心方向。