Jetpack Compose替换自定义加载视图为CircularProgressIndicator时崩溃
Jetpack Compose替换加载组件触发StackOverflowError问题
问题详情
在Jetpack Compose应用中,将自定义加载视图LoadingView替换为Material3的CircularProgressIndicator后,应用会在资源加载完成时崩溃,抛出java.lang.StackOverflowError,堆栈信息显示hasAnchor方法被重复调用,属于Compose运行时异常。
崩溃日志
java.lang.StackOverflowError: stack size 8188KB at java.lang.Object.equals(Object.java:194) at kotlin.jvm.internal.Intrinsics.areEqual(Intrinsics.java:169) at androidx.compose.runtime.GroupSourceInformation.hasAnchor(SlotTable.kt:767) ... (hasAnchor方法重复调用)
相关代码
当注释掉自定义LoadingView(),改用CircularProgressIndicator()时触发崩溃:
@Composable private fun TestPageContent( // 省略参数 isLoading: Boolean ) { Box( modifier = Modifier .fillMaxSize() .background(Color.Background), contentAlignment = Alignment.Center ) { // 其他UI组件... if (isLoading) { //LoadingView() CircularProgressIndicator() } else { LazyColumn( // 配置项... ) { // 列表内容... } } } }
依赖版本
implementation("androidx.activity:activity-compose:1.7.2") implementation("androidx.compose.ui:ui:1.6.0-alpha06") implementation("androidx.compose.ui:ui-graphics:1.6.0-alpha06") implementation("androidx.compose.material3:material3:1.2.0-alpha08")
补充发现
移除TestPageContent中加载控制代码上方的PageTitle组件后,崩溃消失。PageTitle的调用代码:
PageTitle( modifier = Modifier .align(Alignment.TopCenter) .zIndex(1f), text = "Test" )
PageTitle的实现:
Column( modifier = modifier .fillMaxWidth() .height(50.dp), ) { Box(modifier = Modifier .fillMaxWidth() .fillMaxHeight(0.5f) .background(color), contentAlignment = Alignment.Center ) { Text( text = text, fontSize = 24.sp, color = titleColor ) } Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight(0.5f) ) }
解决方向
- 升级到稳定版Compose:你使用的是Compose 1.6.0-alpha06和Material3 1.2.0-alpha08这类预发布版本,这类版本存在较多未修复的运行时bug。建议直接升级到最新的稳定版(比如Compose 1.5.x + Material3 1.1.x),这类StackOverflowError在正式版中大概率已经被修复。
- 调整UI结构:当前所有组件都放在同一个
Box中,加上zIndex修饰符可能干扰了Compose的重组追踪逻辑。可以改用Column作为根容器,将PageTitle固定在顶部,加载/列表区域占据剩余空间:
@Composable private fun TestPageContent( isLoading: Boolean ) { Column(modifier = Modifier.fillMaxSize().background(Color.Background)) { PageTitle( modifier = Modifier.align(Alignment.CenterHorizontally), text = "Test" ) Box( modifier = Modifier.weight(1f).fillMaxSize(), contentAlignment = Alignment.Center ) { if (isLoading) { CircularProgressIndicator() } else { LazyColumn(/*...*/) { /*...*/ } } } } }
- 移除不必要的zIndex:
PageTitle上的zIndex(1f)是冗余的,改用Column的天然层级就能保证标题在上方,移除后可以避免Compose布局层级追踪出现异常。
内容的提问来源于stack exchange,提问作者Monito
相关产品推荐
相关产品推荐

