gpt4 book ai didi

kotlin - 我是否需要在@Composable 中使用 repeatOnLifecycle 扭曲热流的 collectAsState()?

转载 作者:行者123 更新时间:2023-12-05 02:32:27 26 4
gpt4 key购买 nike

我已阅读文章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 是一个MutableStateFlow,它是一个热流。

不知道热流的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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com