Jetpack Compose 中安全地消耗Flow

logo

Jetpack Compose 中安全地消耗Flow

以 Lifecycle 为周期的方式收集流是在 Android 上收集流的推荐方式。如果您正在使用 Jetpack Compose 构建 Android 应用程序,则使用 collectAsStateWithLifecycle API 可以在 Lifecycle 为周期的方式下从您的 UI 中收集流。

collectAsStateWithLifecycle 允许您的应用程序在不需要时保存应用程序资源,例如当应用程序在后台时。保持不必要的资源活动可能会影响用户的设备健康状况。这些资源可能包括 Firebase 查询、位置或网络更新以及数据库连接等。

继续阅读了解有关此 API 的更多信息,以及为什么应该以 Lifecycle 为周期的方式进行收集,以及它与 collectAsState API 的比较。

collectAsStateWithLifecycle

collectAsStateWithLifecycle 是一种可组合的函数,可按 Lifecycle 的方式从流中收集值,并将最新值表示为 Compose State。每次发生新的流发射时,此 State 对象的值都会更新。这会导致重组成中的每个 State.value使用。

默认情况下,collectAsStateWithLifecycle 使用 Lifecycle.State.STARTED 来启动和停止从流中收集值。这发生在 Lifecycle 移动到目标状态时的进入和退出之间。这是您可以在 minActiveState 参数中配置的 Lifecycle 状态。

collectAsStateWithLifecycle默认在应用程序在后台时取消流的收集
以下片段演示了如何使用collectAsStateWithLifecycle来收集ViewModel在组合函数中公开的StateFlow的uiState字段:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */

@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
fun AuthorRoute(
  onBackClick: () -> Unit,
  modifier: Modifier = Modifier,
  viewModel: AuthorViewModel = hiltViewModel()
) {
  val uiState: AuthorScreenUiState by viewModel.uiState.collectAsStateWithLifecycle()

  AuthorScreen(
    authorState = uiState.authorState,
    newsState = uiState.newsState,
    modifier = modifier,
    onBackClick = onBackClick,
    onFollowClick = viewModel::followAuthorToggle,
  )
}

每当AuthorViewModeluiState发出新的AuthorScreenUiState值时,AuthorRoute都会重新组合。有关collectAsStateWithLifecycle的更多用法,请查看Android应用程序中的Now以及其迁移PR。

要开始在项目中使用collectAsStateWithLifecycle API,请将androidx.lifecycle.lifecycle-runtime-compose构件添加到项目中。

// app/build.gradle file
dependencies {
    implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.0"
}

在幕后
在幕后,collectAsStateWithLifecycle的实现使用repeatOnLifecycle API,这是使用View系统在Android中收集流的推荐方式。

collectAsStateWithLifecycle可以使你免于编写下面显示的样板代码,该代码也以受生命周期影响的方式从可组合函数中收集流量。

架构中的流式集合

应用程序构架中的类型不应了解其他类型的实现细节。UI 不应该知道 ViewModel 如何生成 UI 状态。如果 UI 在屏幕上不可见,则流式集合应该停止以释放应用程序资源(如果合适)。

UI 可以通过使用 collectAsStateWithLifecycle 收集 UI 状态来帮助释放资源。视图模型可以通过以收集器感知的方式生成 UI 状态来实现相同的功能。如果没有收集器,例如当 UI 在屏幕上不可见时,可以通过在生成 UI 状态时使用.stateIn(WhileSubscribed)流 API 停止来自数据层的上游流。有关此内容的更多信息,请观看“ Kotlin 流实践”系列讲座中的该部分。要测试以此方式生成 UI 状态的视图模型,请查看测试指南。

在 UI 层中,使用 collectAsStateWithLifecycle 消耗 UI 状态,并在数据层公开反应流时使用 .stateIn(WhileSubscribed) 来产生它。这可以使应用程序在不需要时释放资源
流的消费者和生产者不需要知道彼此的实现方式。在具有多个环境、变体、库和功能的大型应用程序中找出实现细节可能非常耗时。更糟糕的是,维护依赖于实现细节的代码很困难。

保持后台资源处于活动状态

Android 应用程序可以在众多 Android 设备上运行。不幸的是,并非所有设备和用户都拥有无尽的资源。应用程序通常在受限环境中运行。当 Android 应用程序运行时,有一些重要因素会影响用户体验和设备系统健康:

  • CPU 使用率:CPU 是所有设备组件中电池消耗最高的。电池寿命是永恒的用户关注点。如果被滥用,用户可能会卸载您的应用程序。
  • 数据使用量:在应用程序未连接到 Wi-Fi 时减少网络流量可以帮助用户节省金钱。
  • 内存使用率:应用程序如何使用内存可以对设备的整体稳定性和性能产生非常大的影响。
    想要尊重用户、设备系统健康或面向亿万用户的 Android 开发人员应根据市场、设备或国家/地区的情况优化这些不同因素。保持不需要的资源处于活动状态可能对所使用的设备和设备运行的 Android 版本类型产生负面影响。在 UI 层中使用 collectAsStateWithLifecycle 可以使层次结构的其余部分释放资源。

collectAsState 对比

开发人员经常会问:如果 collectAsStateWithLifecycle 是从 Android 的 composable 函数中收集 flow 的最安全方式,我们为什么现在还需要 collectAsState API 呢? 或者为什么不将生命周期感知功能添加到 collectAsState 中,而是要创建一个新的 API?

composable 函数的生命周期与运行 Compose 的平台无关。如《composables 生命周期》页面所述,composable 函数的实例进入 Composition、重新计算 0 或多次,最后离开 Composition。

在组合中,可组合函数实例的生命周期
collectAsState API 遵循组合的生命周期。它在可组合函数进入组合时开始收集流,离开组合时停止收集。collectAsState 是跨平台的 API,可用于收集流。

但是,在 Android 应用程序中使用 Compose 时,Android 生命周期也在如何管理资源方面发挥着至关重要的作用。即使在 Android 应用程序处于后台状态时,Compose 停止重新组合,collectAsState 仍保持收集活动。这使得层次结构中的其余部分无法释放资源。

在 Compose 中,collectAsState 和 collectAsStateWithLifecycle 都有其目的。当开发 Android 应用程序时使用后者,当开发其他平台时使用前者。

collectAsState 迁移到 collectAsStateWithLifecycle 是易如反掌的:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */

@Composable
fun AuthorRoute(
    onBackClick: () -> Unit,
    modifier: Modifier = Modifier,
    viewModel: AuthorViewModel = hiltViewModel()
) {

-   val uiState: AuthorScreenUiState by viewModel.uiState.collectAsState()
+   val uiState: AuthorScreenUiState by viewModel.uiState.collectAsStateWithLifecycle()

    AuthorScreen(
        authorState = uiState.authorState,
        newsState = uiState.newsState,
        modifier = modifier,
        onBackClick = onBackClick,
        onFollowClick = viewModel::followAuthorToggle,
    )
}

以生命周期感知方式收集流是在Android上收集流的推荐方法,以便允许应用程序中的其他部分在需要时释放资源。

如果您正在使用Jetpack Compose构建Android应用程序,请使用collectAsStateWithLifecycle合成功能执行此操作。

参考

https://github.com/android/nowinandroid
https://developer.android.com/topic/architecture/ui-layer#consume-ui-state

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Calvin880828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值