LaunchedEffect() 无法重新启动
LaunchedEffect() cannot be relaunched
从 here 阅读此 LaunchedEffect take a variable number of keys as a parameter that are used to restart the effect whenever one of those keys changes.
。
我正在尝试通过更改密钥并检查 LaunchEffect 是否会重新启动。
这是我的代码:
private const val SplashWaitTime: Long = 2000
@Composable
fun LandingScreen(modifier: Modifier = Modifier, onTimeout: () -> Unit) {
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
val currentOnTimeout by rememberUpdatedState(onTimeout)
var key = 1
LaunchedEffect(key) {
Log.w("xx", "Launched effect is running key = $key")
delay(SplashWaitTime)
key = 2
currentOnTimeout()
}
key = 3
Image(painterResource(id = R.drawable.ic_crane_drawer), contentDescription = null)
}
}
使用上面的代码,运行打开应用程序,我可以看到 Logcat.
中只有一个日志打印
即:
2022-05-08 18:42:35.951 20101-20101/androidx.compose.samples.crane W/xx: Launched effect is running key = 3
所以问题是:
- 如何确保 LaunchEffect 可以 运行 且 key = 1 首先?然后使用 key = 3.
重新启动
- 为什么 key = 2 不会触发 LaunchEffect 重新启动?
更新:
我的Android工作室:
Android Studio Chipmunk | 2021.2.1 Beta 4
Build #AI-212.5712.43.2112.8233820, built on March 1, 2022
Runtime version: 11.0.12+0-b1504.28-7817840 x86_64
我的撰写版本是1.1.1
更新 2:
我接受@MARSK 的回答。只是想在这里放更多信息以供其他伙伴参考。
我正在遵循代码路径这个 codelab。所以上面的代码是其中的一部分,我认为这里的重点是:
- 键应该定义为状态,如
remember { mutableStateOf(1) }
- 预期的结果应该是无限循环,因为在 LaunchedEffect 块内部,语句 key = 2 将始终触发重组。
为什么我无法弄清楚它是如何工作的,而且我只打印了一份日志?那是因为 onTimeout 回调,从 LandingScreen 可组合项的父级,该函数将从树中完全删除这个(LandingScreen)可组合项,因此它没有任何机会被重新组合。
var key by remember { mutableStateOf (1) }
以上是它工作的关键。代码按预期工作。这是详细信息。
当你运行这个简单的代码块
var key by remember { mutableStateOf(1) }
LaunchedEffect(key) {
Log.e("xx", "Running key $key")
delay(2000)
key = 2
}
key = 3
代码运行s为:key初始化为1,效果运行s为key = 1
的值,但是,as正确(我希望)指出根据下面评论中的 OP,LaunchedEffect
需要一些时间来生成协程,这足以让控件转移到下一条语句并将键的值更改为 3。这确保了永远不会记录 key 的值为 1。
此后延迟两秒,键的值变为 1,触发可组合项的整个重组,这意味着整个可组合项应 re-execute。这是怎么回事:
密钥保持为 2,因为我们使用 remember
LaunchedEffect 被调用时值为 2,但同样,由于 coroutine-spawning 时间,密钥被修改为 3,这与 2 不同,RE-TRIGGERS 重组,因此,永远不会记录2,但只记录 3,因为那是 key
现在的值。同样,之前的LaunchedEffect
并没有被取消,当它的two-second延迟结束后,它会再次将值切换为2
,它立即移回3
,因为这个作文。因此,您将始终如一地获得 Running 3
的日志,两个日志在时间上非常接近,而下一个日志将被 two-second 间隔分隔。
这就是你得到的
17:28:43.241 : Running key 3
17:28:43.269 : Running key 3
17:28:45.298 : Running key 3
17:28:45.318 : Running key 3
17:28:47.356 : Running key 3
17:28:47.374 : Running key 3
17:28:49.422 : Running key 3
17:28:49.443 : Running key 3
17:28:51.501 : Running key 3
17:28:51.534 : Running key 3
17:28:53.591 : Running key 3
17:28:53.607 : Running key 3
17:28:55.649 : Running key 3
17:28:55.689 : Running key 3
现在,如果您希望正确记录调用效果的值,则需要将其存储在入口点本身。像这样,
var key by remember { mutableStateOf(1) }
var keyStore: Int
LaunchedEffect(key.also { keyStore = key }) {
"Running key $keyStore".log()
delay(2000)
key = 2
}
key = 3
这会生成正确的运行时间日志
17:34:13.790 : Running key 1
17:34:13.821 : Running key 3
17:34:15.847 : Running key 2
17:34:15.862 : Running key 3
17:34:17.903 : Running key 2
17:34:17.922 : Running key 3
17:34:19.982 : Running key 2
17:34:20.015 : Running key 3
17:34:22.055 : Running key 2
17:34:22.073 : Running key 3
17:34:24.135 : Running key 2
17:34:24.154 : Running key 3
从 here 阅读此 LaunchedEffect take a variable number of keys as a parameter that are used to restart the effect whenever one of those keys changes.
。
我正在尝试通过更改密钥并检查 LaunchEffect 是否会重新启动。
这是我的代码:
private const val SplashWaitTime: Long = 2000
@Composable
fun LandingScreen(modifier: Modifier = Modifier, onTimeout: () -> Unit) {
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
val currentOnTimeout by rememberUpdatedState(onTimeout)
var key = 1
LaunchedEffect(key) {
Log.w("xx", "Launched effect is running key = $key")
delay(SplashWaitTime)
key = 2
currentOnTimeout()
}
key = 3
Image(painterResource(id = R.drawable.ic_crane_drawer), contentDescription = null)
}
}
使用上面的代码,运行打开应用程序,我可以看到 Logcat.
中只有一个日志打印即:
2022-05-08 18:42:35.951 20101-20101/androidx.compose.samples.crane W/xx: Launched effect is running key = 3
所以问题是:
- 如何确保 LaunchEffect 可以 运行 且 key = 1 首先?然后使用 key = 3. 重新启动
- 为什么 key = 2 不会触发 LaunchEffect 重新启动?
更新:
我的Android工作室:
Android Studio Chipmunk | 2021.2.1 Beta 4
Build #AI-212.5712.43.2112.8233820, built on March 1, 2022
Runtime version: 11.0.12+0-b1504.28-7817840 x86_64
我的撰写版本是1.1.1
更新 2: 我接受@MARSK 的回答。只是想在这里放更多信息以供其他伙伴参考。
我正在遵循代码路径这个 codelab。所以上面的代码是其中的一部分,我认为这里的重点是:
- 键应该定义为状态,如
remember { mutableStateOf(1) }
- 预期的结果应该是无限循环,因为在 LaunchedEffect 块内部,语句 key = 2 将始终触发重组。
为什么我无法弄清楚它是如何工作的,而且我只打印了一份日志?那是因为 onTimeout 回调,从 LandingScreen 可组合项的父级,该函数将从树中完全删除这个(LandingScreen)可组合项,因此它没有任何机会被重新组合。
var key by remember { mutableStateOf (1) }
以上是它工作的关键。代码按预期工作。这是详细信息。
当你运行这个简单的代码块
var key by remember { mutableStateOf(1) }
LaunchedEffect(key) {
Log.e("xx", "Running key $key")
delay(2000)
key = 2
}
key = 3
代码运行s为:key初始化为1,效果运行s为key = 1
的值,但是,as正确(我希望)指出根据下面评论中的 OP,LaunchedEffect
需要一些时间来生成协程,这足以让控件转移到下一条语句并将键的值更改为 3。这确保了永远不会记录 key 的值为 1。
此后延迟两秒,键的值变为 1,触发可组合项的整个重组,这意味着整个可组合项应 re-execute。这是怎么回事:
密钥保持为 2,因为我们使用 remember
LaunchedEffect 被调用时值为 2,但同样,由于 coroutine-spawning 时间,密钥被修改为 3,这与 2 不同,RE-TRIGGERS 重组,因此,永远不会记录2,但只记录 3,因为那是 key
现在的值。同样,之前的LaunchedEffect
并没有被取消,当它的two-second延迟结束后,它会再次将值切换为2
,它立即移回3
,因为这个作文。因此,您将始终如一地获得 Running 3
的日志,两个日志在时间上非常接近,而下一个日志将被 two-second 间隔分隔。
这就是你得到的
17:28:43.241 : Running key 3
17:28:43.269 : Running key 3
17:28:45.298 : Running key 3
17:28:45.318 : Running key 3
17:28:47.356 : Running key 3
17:28:47.374 : Running key 3
17:28:49.422 : Running key 3
17:28:49.443 : Running key 3
17:28:51.501 : Running key 3
17:28:51.534 : Running key 3
17:28:53.591 : Running key 3
17:28:53.607 : Running key 3
17:28:55.649 : Running key 3
17:28:55.689 : Running key 3
现在,如果您希望正确记录调用效果的值,则需要将其存储在入口点本身。像这样,
var key by remember { mutableStateOf(1) }
var keyStore: Int
LaunchedEffect(key.also { keyStore = key }) {
"Running key $keyStore".log()
delay(2000)
key = 2
}
key = 3
这会生成正确的运行时间日志
17:34:13.790 : Running key 1
17:34:13.821 : Running key 3
17:34:15.847 : Running key 2
17:34:15.862 : Running key 3
17:34:17.903 : Running key 2
17:34:17.922 : Running key 3
17:34:19.982 : Running key 2
17:34:20.015 : Running key 3
17:34:22.055 : Running key 2
17:34:22.073 : Running key 3
17:34:24.135 : Running key 2
17:34:24.154 : Running key 3