提问人:NewPartizal 提问时间:7/25/2023 最后编辑:NewPartizal 更新时间:7/26/2023 访问量:950
什么是 DisposableEffect 和 jetpack Compose 中的引擎盖下?
what is DisposableEffect and under the hood in jetpack compose?
问:
一段时间以来,我一直在试图了解什么是DisposableEffect以及它是如何工作的,所以我在互联网上搜索了一下,我看到大多数文档都是类似的解释,例如
DisposableEffect 是 Jetpack Compose 提供的强大工具, 允许您在可组合函数中执行副作用 当可组合物离开组合物时需要清理。你 可以使用键来控制何时调用回调函数。
我知道 DisposableEffect 像 LaunchedEffect 一样异步工作并基于键值,但是当 onDispose 方法工作时,您可以看到上面的定义
当可组合物离开组合物时需要清理
这句话可能定义了 onDispose 方法,所以在这种情况下,它意味着 onDispose 会起作用,但是当可组合项离开组合到处都这样写时,这意味着什么?我无法理解。
例如,我是这样做的
州
data class State(
...
val isError:Int?=null,
...
)
用户界面
val errMsg = stringResource(id = R.string.error)
val savedMsg = stringResource(id = R.string.saved)
DisposableEffect(state.isError) {
when (state.isError) {
0 -> Toast.makeText(context, savedMsg, Toast.LENGTH_LONG).show()
1 -> Toast.makeText(context, errMsg, Toast.LENGTH_LONG).show()
else -> {}
}
onDispose {
setIsError()
}
}
虚拟机
fun setIsError(){
_state.update {
it.copy(
isError = null,
)
}
}
那么,例如,在Dispose上何时运行?
这就是为什么我在这里每次用户按下按钮时都使用 onDisposableEffect,如果按下按钮时操作成功,则出现 isError 0,如果不是 1,我想在每次成功操作时都收到一条 Success 消息,但是一旦按下按钮并且操作成功,Success 消息不起作用,因为键值是 isError 仍然相同 0, 所以我使用 DisposableEffect 来解决这个问题,但正如我所说,我不知道细节,也没有完全理解
答:
请考虑以下示例代码:
@Composable
fun example() {
var inComposition by remember { mutableStateOf(true) }
if (inComposition) {
DisposableEffect {
...
}
}
}
当变量从 到 时,将离开组合,从而运行其函数。DisposableEffect
onDispose
inComposition
true
false
评论
Toast
setIsError
error
DisposableEffect
是一个函数,因为它观察记忆状态,而后者带有一个 .remember
LaunchedEffect
coroutineScope
dispose
当块/可组合项由于 RememberObserver 的 onForgotten 函数而离开组合时,函数将被调用,如下所示。DisposableEffect
此实现类似于 LaunchedEffect 仅工作一次
@Composable
@NonRestartableComposable
fun DisposableEffect(
key1: Any?,
effect: DisposableEffectScope.() -> DisposableEffectResult
) {
remember(key1) { DisposableEffectImpl(effect) }
}
LaunchedEffect
@Composable
@NonRestartableComposable
@OptIn(InternalComposeApi::class)
fun LaunchedEffect(
key1: Any?,
block: suspend CoroutineScope.() -> Unit
) {
val applyContext = currentComposer.applyCoroutineContext
remember(key1) { LaunchedEffectImpl(applyContext, block) }
}
处置工作原理部分是
private val InternalDisposableEffectScope = DisposableEffectScope()
private class DisposableEffectImpl(
private val effect: DisposableEffectScope.() -> DisposableEffectResult
) : RememberObserver {
private var onDispose: DisposableEffectResult? = null
override fun onRemembered() {
onDispose = InternalDisposableEffectScope.effect()
}
override fun onForgotten() {
onDispose?.dispose()
onDispose = null
}
override fun onAbandoned() {
// Nothing to do as [onRemembered] was not called.
}
}
这基本上就是记忆观察的生命周期。
当您移动到下一页时,退出条件块或将项目滚动出 LazyColumn/Row 的视口,onDispose 可用于观察块何时离开组合。
评论