Android Jetpack 协程完成后如何调用 Composable Function?

问题描述 投票:0回答:1

我想在协程完成后启动一个 LaunchedEffect。

val dataStore = StoreAppSettings(ctx)
    val scope = rememberCoroutineScope()

    scope.launch {
        dataStore.getCycleStart.collectLatest { vm.cycleStart = it }
        dataStore.getSmartCycle.collectLatest { vm.smartCycle = it  }
        scope.cancel()
    }

    if (vm.categories.isNotEmpty() && !scope.isActive) {
        LaunchedEffect(key1 = ctx){
            vm.updateTransactionState()
        }
    }

我尝试取消范围并检查范围是否处于活动状态,但显然它不起作用

android android-jetpack-compose kotlin-coroutines coroutine launched-effect
1个回答
0
投票

Compose 是基于状态的,因此您不必等待某些协程完成,而是您的异步代码会更新状态,以便您的可组合项可以在状态发生变化时重新组合。

所有非 UI 特定的异步代码(例如,从数据存储中读取值)都属于视图模型。从那里它作为一个 StateFlow 公开,可以在您的可组合项中观察到更改。

视图模型中的

cycleStart
smartCycle
属性应如下所示:

private val dataStore = StoreAppSettings(applicationContext)

val cycleStart: StateFlow<Boolean?> = dataStore.getCycleStart.stateIn(
    scope = viewModelScope,
    started = SharingStarted.WhileSubscribed(5_000),
    initialValue = null,
)

val smartCycle: StateFlow<String?> = dataStore.getSmartCycle.stateIn(
    scope = viewModelScope,
    started = SharingStarted.WhileSubscribed(5_000),
    initialValue = null,
)

由于从您的代码中不清楚数据存储首选项是什么类型,我只是假设在此示例中它们是布尔值和字符串。将其更改为实际情况。

这些属性现在是可以在可组合项中收集的流:

val cycleStart by vm.cycleStart.collectAsStateWithLifecycle()
val smartCycle by vm.smartCycle.collectAsStateWithLifecycle()

为此,您需要 gradle 依赖项

androidx.lifecycle:lifecycle-runtime-compose

这些变量现在始终使用数据存储中的当前内容进行更新。当发生变化时,这些变量将立即更新并触发重组,以便您的 UI 可以对新值做出反应。

您的 UI 代码应该只描述根据变量的当前内容应该发生什么。它们将包含

null
,直到检索到的数据存储读取首选项,因此您可以简单地使用
if (cycleStart != null)
之类的内容来显示对于给定
cycleStart
应该可见的 UI。

但是,您应该触发某些视图模型逻辑作为响应。这应该由视图模型本身来完成。

无论

vm.updateTransactionState()
做什么,这可能应该由视图模型响应新的流量值来完成。为此,您可以使用流运算符,例如
mapLatest
flatMapLatest
onEach
等。将它们应用到
stateIn
之前的流中。如果需要both流的值,也可以用
combine
将它们合并到on流中。

© www.soinside.com 2019 - 2024. All rights reserved.