Jetpack Compose如何获取绑定指定Key的rememberCoroutineScope
带Key绑定的Compose协程作用域实现方案
原生rememberCoroutineScope仅会在Composable离开Composition时自动取消协程,不会响应参数变化触发取消,我们可以自行封装一个完全符合需求的版本,行为和原生保持一致,额外增加Key变化自动取消的能力。
封装实现代码
import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CloseableCoroutineScope import kotlinx.coroutines.Job @Composable inline fun rememberCoroutineScope(vararg keys: Any?): CoroutineScope { val originScope = rememberCoroutineScope() val keyedScope = remember(*keys) { CloseableCoroutineScope(originScope.coroutineContext + Job(originScope.coroutineContext[Job])) } DisposableEffect(keyedScope) { onDispose { keyedScope.cancel() } } return keyedScope }
行为说明
- 继承原生协程作用域的全部特性:协程上下文和Composition绑定,当Composable离开Composition时,作用域会跟随原生作用域自动取消
- 当传入的任意Key发生变化时,旧的协程作用域会在重组时被自动取消,同时生成新的协程作用域供后续使用
- 完全继承原生作用域的上下文配置,包括全局配置的协程调度器、异常处理器等,不会破坏原有协程上下文的配置
使用示例
基础用法
完全匹配预期的调用方式:
@Composable fun Sth(sth: Int) { val coroutineScope = rememberCoroutineScope(sth) // 示例:点击事件启动协程 Button(onClick = { coroutineScope.launch { // 执行异步逻辑,当sth变化或页面退出时,未完成的协程会自动取消 } }) { Text("触发异步任务") } }
Indication场景适配
自定义Indication场景可以直接使用该封装,当interactionSource变化时旧作用域自动取消,避免协程泄漏:
class SomeIndication( val a: Int, val b: Int ) : Indication { @Composable override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance { val coroutineScope = rememberCoroutineScope(interactionSource) return remember(interactionSource) { val sth: State<Int> = sth(a, b, coroutineScope) object: IndicationInstance { override fun ContentDrawScope.drawIndication() { drawContent() drawSomething(sth.value) } } } } }
内容的提问来源于stack exchange,提问作者daniyelp
相关产品推荐
相关产品推荐

