Kotlin中协程的管理
在 Jetpack Compose 里,协程的生命周期管理要跟 UI 的生命周期 绑定,否则很容易出现 页面退出后协程还在跑 的情况。常见的做法有以下几种:
1.使用LaunchedEffect
LaunchedEffect会跟随Composable的生命周期。退出页面时会自动取消里面的协程。
@Composable
fun MyScreen() {LaunchedEffect(Unit) {// 这里的协程会随着页面退出而自动取消repeat(10) {delay(1000)println("tick $it")}}
}
页面销毁 / Composable 移除时,LaunchedEffect
内部的协程会被自动取消。
2.使用 rememberCoroutineScope
(需要手动控制)
rememberCoroutineScope()
会创建一个作用域,跟随 Composable 的生命周期。如果你需要手动取消,可以这样:
@Composable
fun MyScreen() {val scope = rememberCoroutineScope()DisposableEffect(Unit) {onDispose {// 页面销毁时 scope 自动取消scope.cancel()}}Button(onClick = {scope.launch {delay(3000)println("task done")}}) {Text("Start Task")}
}
3.使用ViewModelScope(推荐用于业务逻辑)
如果协程任务是跟页面数据逻辑相关而不是纯UI,可以放在ViewModel里,利用ViewModelScope。ViewModel被销毁时,协程自动取消:
class MyViewModel : ViewModel() {fun startJob() {viewModelScope.launch {delay(5000)println("done")}}
}@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {Button(onClick = { viewModel.startJob() }) {Text("Start")}
}
总结
UI 短任务 → 用
LaunchedEffect
,退出页面自动取消。需要手动控制 → 用
rememberCoroutineScope + DisposableEffect
。业务逻辑任务 → 放在
ViewModel
里,用viewModelScope
,生命周期跟 ViewModel 走。