在一个Activity下有一个屏幕级可组合.当用户被导航到那个屏幕时,我使用LaunchedEffect(Unit) {}来调用view-model函数,它做了一些工作.现在,在设备旋转或发生任何配置更改之前,此操作都可以正常工作.在大约旋转之后,再次执行LaunchedEffect(Unit) {},这是不希望的.

我知道我可以在视图模型中或在可组合函数本身中使用标志来防止再次执行该工作.但是,写在这里是为了找出这个问题是否有任何理想的解决方案,因为这似乎是Jetpack Compose中的一个常见问题.

PS:该功能需要在屏幕级别的视图模型中,而不是在活动级别.此外,不能使用init的view-Model作为屏幕级Composable调用的函数,需要一些数据作为它的参数.

推荐答案

您可以在ViewModel中实现一些基本的缓存.以下是ViewModel在配置更改期间将缓存数据返回给订阅者的假设示例.

class MainViewModel : ViewModel() {
    sealed interface MainViewState {
        data object Content : MainViewState
        data object Loading : MainViewState
        data class Error(val error: Throwable) : MainViewState
    }

    private val _viewState: MutableStateFlow<MainViewState> =
        MutableStateFlow(MainViewState.Loading)

    val viewState = _viewState.asStateFlow()

    init {
       loadData()
    }

    private fun loadData() = viewModelScope.launch {
        // We have cached data, do nothing, StateFlow will re-emit latest state to new subscribers
        if (_viewState.value == MainViewState.Content) {
            return@launch
        }

        _viewState.update {
            MainViewState.Loading
        }

        // Load some data and return MainViewState.Content or MainViewState.Error
    }
}

Android相关问答推荐

打开平板电脑的下载文件夹中的文件,例如使用其mimeType将Intent发送到我们的应用程序

Android深度链接配置中的URL片段匹配'

使用不同的Google帐户登录

Android Compose Lazy柱形实时UI更改

Android 11:在try 获取文件的永久权限后,仍然没有读写权限

Android-交叉引用表中的ForeignKey用于什么?

如何在Jetpack Compose中创建这个圆形?

Android 12+BLE字节不同

将输出写入已发布的 Android 应用程序中的日志(log)文件?

Spinner - onItemLongClick 从未执行

Android Studio 在 list 文件中已经声明了活动类,但仍出现无法找到明确的活动类的错误

Android 访问任意公共目录

为一组闪烁的可组合项制作动画,控制同步/定时

状态更改后 colored颜色 未正确更改

compose 导航参数字符串包含花括号?

在移动设备上看到时如何增加 PasswordField 文本?

java.lang.String 类型的值 Forbidden 无法转换为 JSONObject

JCenter 是否永久关闭(10 月 31 日)?

有人可以向我解释这两个结果有什么区别吗?

如何授予对 Uri 图像的永久权限(androidx)