Android composecollectAsStateWithLifecycle 在可组合死亡后停止收集值

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

我有一个可组合的小部件,在应用程序进入后台或屏幕在底部导航更改后进入后退堆栈后,它使用 RememberSaveable 来生存。这是小部件的代码:

    val banner = bannerViewModel.bannerStateFlow.collectAsStateWithLifecycle(null)
    val rememberedBanner = rememberSaveable { banner }

另一方面,小部件使用连接到用例的视图模型,然后连接到存储库来收集信息,这是视图模型中的代码:

@HiltViewModel
internal class BannerViewModel @Inject constructor (
    private val savedStateHandle: SavedStateHandle,
    private val getBannerUseCase: GetBannerUseCase
): ViewModel() {

    @OptIn(ExperimentalCoroutinesApi::class)
    val bannerStateFlow = savedStateHandle.getStateFlow<Banner?>(
        key = "bannerInfoResourceId",
        initialValue = null
    ).flatMapLatest {
        getBannerUseCase()
    }
    .stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5_000),
        initialValue = null
    ).onStart {
        println("bannerFromFlow onStart - ViewModel")
    }.onCompletion {
        println("bannerFromFlow onCompletion - ViewModel")
    }
}

存储库连接到 Firebase 实时数据库数据源并使用流程保持连接,一切正常,您在 Firebase 中更改值,我会立即在 UI 上看到该更改。但是,一旦我导航其他应用程序的部分,然后返回到此小部件,UI 就会从保存的状态恢复(您可以看到小部件没有重新组合),但 Firebase 中更改的新值不再在 UI 中更新。我调试了流程,似乎正在工作并接收新值,就像 CollectAsStateWithLifecycle 不再从流程中收集值一样。

有什么线索吗?

android-jetpack-compose lifecycle
1个回答
0
投票

rememberedBanner
保存了
State
在初始合成时创建的
bannerViewModel.bannerStateFlow.collectAsStateWithLifecycle(null)
并且从不更新它,同时存储在
State
中的
banner
将在每次重新创建屏幕时更新。

您可能想要的是记住该值,而不是

State
本身。要保持
rememberedBanner
更新,您还应该指定值,更改后将重新初始化
rememberSaveable
状态。

val rememberedBanner = rememberSaveable(banner.value) { banner.value }

尽管如此,这似乎是毫无意义的额外工作。为什么不直接使用

banner.value

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