android runtime_error ai_generated true

java.lang.StackOverflowError: 栈大小8MB在androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd

java.lang.StackOverflowError: stack size 8MB at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd

ID: android/compose-recomposition-infinite-loop

其他格式: JSON · Markdown 中文 · English
86%修复率
83%置信度
1证据数
2023-11-20首次发现

版本兼容性

版本状态引入弃用备注
Compose BOM 2024.01.00 active
Compose Compiler 1.5.8 active
Kotlin 1.9.22 active
Android 14 (API 34) active

根因分析

Jetpack Compose中无限重组循环,由于状态变量在组合期间被更新(例如,在没有正确键的LaunchedEffect中调用setState,或触发重新渲染的可组合lambda中)。

English

Infinite recomposition loop in Jetpack Compose due to a state variable being updated during composition (e.g., calling setState inside a LaunchedEffect without proper key or in a composable lambda that triggers re-render).

generic

官方文档

https://developer.android.com/jetpack/compose/state#side-effects-in-compose

解决方案

  1. Move the state update outside of composition by using LaunchedEffect with a stable key. Example: LaunchedEffect(Unit) { delay(100); myState.value = newValue } instead of LaunchedEffect(myState.value) { ... }
  2. Use remember with a derivedStateOf to compute values without triggering recomposition. Example: val derivedValue by remember { derivedStateOf { computeExpensive(myState.value) } }
  3. Add a snapshotFlow block to observe state changes outside composition. Example: LaunchedEffect(Unit) { snapshotFlow { myState.value }.collect { /* update other state */ } }

无效尝试

常见但无效的做法:

  1. Increase stack size via AndroidManifest android:largeHeap="true" 95% 失败

    largeHeap increases heap memory, not stack size. Stack size is fixed per thread in Android (8MB default). This does not fix the infinite loop.

  2. Wrap the state update in withFrameMillis or withFrameNanos 80% 失败

    These APIs schedule work on the next frame but do not prevent the recomposition loop if the state is still updated during composition.