我将我的应用程序从普通的SQLite迁移到使用Room,以使其更加强大. 现在我有了一个Flow,它从我的ASO内的数据库中查询所有用户:

@Query("SELECT * FROM users")
fun getAllAsFlow(): Flow<List<UserData>>

在我的存储库中,我将其公开为:

val allUsersFlow: Flow<List<UserData>> = userDao.getAllAsFlow()

然后在我的视图模型中:

val allUsers: Flow<List<UserData>> = repository.allUsersFlow

最终将其收集在具有生命力的可组合物中

 val users by usersPageViewModel.allUsers.collectAsStateWithLifecycle(initialValue = listOf())

现在一切都按预期运行,但当我导航到另一个页面(通过按栈),然后再次弹出它时,Compable会重新组合,用户在再次获取数据之前是一个空列表,这导致屏幕视图一瞬间空.

现在,如果我用collectAsState替换collectAsStateWithLifecycle,这种情况不会发生,因为集合不知道第一个屏幕进入后台.

那么,实现collectAsState行为的最佳方法是什么,但仍然了解应用程序的全球生命周期(例如,进入后台).我可以通过collectAsStateWithLifecycle种主要活动生命周期吗?

推荐答案

在您的视图模型中,您只需要将存储库中的cold流转换为hot StateFlow:

val allUsers: StateFlow<List<UserData>> = repository.allUsersFlow.stateIn(
    scope = viewModelScope,
    started = SharingStarted.WhileSubscribed(5_000),
    initialValue = emptyList(),
)

这样,您的视图模型始终具有流的价值,并且可以在需要时提供它.

由于您现在在视图模型中提供了initialValue,因此您可以将其从组合中的collectAsStateWithLifecycle中删除.

Android相关问答推荐

Android设备.Net Maui上的mp3文件列表

如何从URI中获取图像大小

Android Kotlin ImageView内置于Kotlin ImageView中.适配器未按预期更新

不能有意地从一个活动的可组合功能转移到另一个活动

Android写/读二进制文件到共享存储

从不可组合回调打开可组合屏幕

面向Jetpack Compose的可组合放置问题

Android 访问任意公共目录

如何删除房间数据库?

如何添加到先前预填充的 Room 数据库?

Android工作室未成立

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

状态值更改时屏幕未重新组合 - Jetpack Compose

Kotlin 调用带参数的函数 Any is xxx ||任何 yyy 都不起作用

Android WebView 没有在第一次页面完成时从本地存储读取数据?

单击登录按钮后从应用程序中退出

当我更改 ViewModel var 时,Kotlin + Compose 中的 Composable 不会更新

在 Compose 中使用 DeepLink 会导致无法向后导航

如何使用 Glide 将图像下载到设备内部存储

我可以在不解密的情况下使用 JSch 获取加密的 SSH 私钥的类型或 fingerprint 吗?