Jetpack Compose Flow、StateFlow与State
# 前言
以下内容为学习笔记,不保证内容的准确性!
虽然 Jetpack Compose 的状态管理很容易让人血压升高,但如果用不好状态管理会让人血压更高。
# Flow 与 StateFlow
下面表格来自 DeepSeek:
特性 | Flow | StateFlow |
---|---|---|
冷流 vs 热流 | 冷流(Cold Stream) | 热流(Hot Stream) |
数据发射时机 | 每次调用 collect 时从头开始发射数据 | 持有当前值,立即发送给新收集者 |
适用场景 | 异步数据流(如网络请求、数据库查询) | UI 状态管理(如主题、登录状态) |
值的保留 | 无状态,不保留数据 | 始终持有最新值 |
值的更新触发条件 | 每次 collect 都会触发数据发射 | 仅当新值与旧值不同时触发更新(equals 比较) |
# Flow 转 StateFlow
1 | val stateFlow: StateFlow<Data> = someFlow.stateIn( |
# 使用
两者均可以通过 collectAsStateWithLifecycle()
或者 collectAsState()
转换为 State
供 Compose UI 使用。
如果需要在收集时处理数据,也可以使用 collect()
:
1 | stateFlow.collect{item-> |
需要注意的是,当使用 collect 后会持续订阅,因此只需订阅一次即可。在 Compose 中可以使用 LaunchedEffect(Unit)
来进行订阅操作, LaunchedEffect(Unit)
在整个生命周期中只会执行一次,适合于这种只需执行一次的代码。当然,重复执行 collect 进行订阅也没问题,stateFlow 会自动停止之前的订阅然后重新开始新的订阅。
# StateFlow 与 State
# 设计目的
由 DeepSeek 分析:
-
State
-
专为 Compose 设计,用于在可组合函数(Composable)中跟踪和响应局部 UI 状态的变化。
-
通过 mutableStateOf 创建,当值变化时,会自动触发 UI 重组(Recomposition)。
-
适用于简单的 UI 状态管理,例如按钮的选中状态、文本输入值等。
-
StateFlow
-
属于 Kotlin 的响应式流(Flow)的一部分,用于在应用的不同层之间共享状态(如 ViewModel 到 UI 层)。
-
需要手动通过 collect 或 collectAsState 订阅数据流,适合处理跨组件或跨生命周期的状态共享。
-
更适用于复杂业务逻辑的状态管理,例如从网络请求或数据库加载数据。
# 适用场景
State
比较适合 UI 内的临时变量,如 TextField 的 text 的值,Switch 的 checked 的值等
因为 Compose 设计为单向数据流,所以需要使用 State 来保存重组前上一次的值。
StateFlow
适合于共享状态,特别是在 ViewModel 中供多个 UI 控件进行观察。
并且使用 remember
的 State
在退出组合时数据将被丢弃,而 StateFlow
的生命周期通常跟随 ViewModel,在退出组合时数据不会出现丢失。
有点像传统 Android xml 开发里将数据保存在 ViewModel 中防止因切换主题暗色模式或者切换横竖屏而导致 UI 状态丢失。
# 使用
State
结合 remember
和 mutableStateOf
,就像普通变量一样使用即可
StateFlow
则需要使用 collect
或 collectAsState()
订阅状态:
1 | val stateFlow by ViewModel.stateFlow.collectAsState() |
Use this card to join MyBlog and participate in a pleasant discussion together .
Welcome to GoodBoyboy 's Blog,wish you a nice day .