- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已阅读文章A safer way to collect flows from Android UIs .
我知道以下内容。
由 channel 支持或使用带有缓冲区的运算符(例如 buffer、conflate、flowOn 或 shareIn)的冷流使用某些现有 API(例如 CoroutineScope.launch、Flow.launchIn 或LifecycleCoroutineScope.launchWhenX,除非你在activity进入后台时手动取消启动协程的Job。这些 API 将保持底层流生产者处于事件状态,同时在后台将项目发送到缓冲区,从而浪费资源。
代码A来自官方样本project .
viewModel.suggestedDestinations
是一个MutableStateFlo
w,它是一个热流。
不知道热流的collectAsState()
操作在@Composable UI中是否安全。
1:我是否需要像代码 B 或代码 C 那样使用代码来代替代码 A 来实现热流量?
2:cold Flow的操作collectAsState()
在@Composable UI中是否安全。
代码A
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun CraneHomeContent(
onExploreItemClicked: OnExploreItemClicked,
openDrawer: () -> Unit,
modifier: Modifier = Modifier,
viewModel: MainViewModel = viewModel(),
) {
val suggestedDestinations by viewModel.suggestedDestinations.collectAsState()
...
}
@HiltViewModel
class MainViewModel @Inject constructor(
...
) : ViewModel() {
...
private val _suggestedDestinations = MutableStateFlow<List<ExploreModel>>(emptyList())
val suggestedDestinations: StateFlow<List<ExploreModel>>
}
代码 B
class LocationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
...
}
}
}
}
代码 C
@Composable
fun LocationScreen(locationFlow: Flow<Flow>) {
val lifecycleOwner = LocalLifecycleOwner.current
val locationFlowLifecycleAware = remember(locationFlow, lifecycleOwner) {
locationFlow.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
}
val location by locationFlowLifecycleAware.collectAsState()
...
}
最佳答案
collectAsState
(代码 A)对于任何类型的流都是安全的(冷/热无关紧要)。如果您查看 collectAsState
是如何实现的,那么您会发现它在深处使用了 LaunchedEffect
(collectAsState
-> produceState
-> LaunchedEffect
)
internal class LaunchedEffectImpl(
parentCoroutineContext: CoroutineContext,
private val task: suspend CoroutineScope.() -> Unit
) : RememberObserver {
private val scope = CoroutineScope(parentCoroutineContext)
private var job: Job? = null
override fun onRemembered() {
job?.cancel("Old job was still running!")
job = scope.launch(block = task)
}
override fun onForgotten() {
job?.cancel()
job = null
}
override fun onAbandoned() {
job?.cancel()
job = null
}
}
它创建一个协程范围并在它进入组合后启动 task
lambda,并在它离开组合后自动取消它。
在代码 A 中,viewModel.suggestedDestinations.collectAsState()
(连同它的 LaunchedEffect 和它的协程作用域)将在 CraneHomeContent
被调用时处于事件状态其他代码。一旦 CraneHomeContent
停止被调用,collectAsState()
中的 LaunchedEffect
就会被取消(以及协程作用域)。
如果从多个地方调用它,那么会有多个 LaunchedEffect
,因此会有多个协程作用域。
关于kotlin - 我是否需要在@Composable 中使用 repeatOnLifecycle 扭曲热流的 collectAsState()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71246146/
我正在使用 Composes collectAsState() 函数从此 StateFlow 进行收集 val _authToken = MutableStateFlow(AuthToken("",
根据这些文章,我正在尝试遵循官方指南,使用 Compose 从 LiveData 迁移到 Flow/StateFlow: A safer way to collect flows from Andro
我已阅读文章A safer way to collect flows from Android UIs . 我知道以下内容。 由 channel 支持或使用带有缓冲区的运算符(例如 buffer、co
我有一个文件列表,需要从每个文件中查询数据,然后将 Result 列表渲染到 LazyColumn 但是在所有查询完成之前我不想渲染列表,就像这样: class Repo { private
我是一名优秀的程序员,十分优秀!