Simon Stahl
01/19/2022, 1:16 AMIllegalStateException: LayoutNode should be attached to an owner
(see comments for more info)LazyRow
with about 50 items. Each item consists of an image as well as 3 icons. When I use animateScrollToItem(idx)
, I get following excepion:
java.lang.IllegalStateException: LayoutNode should be attached to an owner
at androidx.compose.ui.node.LayoutNodeKt.requireOwner(LayoutNode.kt:1433)
at androidx.compose.ui.node.ModifierLocalConsumerNode.notifyConsumerOfChanges(ModifierLocalConsumerNode.kt:42)
at androidx.compose.ui.node.ModifierLocalConsumerNode.access$notifyConsumerOfChanges(ModifierLocalConsumerNode.kt:23)
at androidx.compose.ui.node.ModifierLocalConsumerNode$Companion$onReadValuesChanged$1.invoke(ModifierLocalConsumerNode.kt:49)
at androidx.compose.ui.node.ModifierLocalConsumerNode$Companion$onReadValuesChanged$1.invoke(ModifierLocalConsumerNode.kt:48)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ApplyMap.callOnChanged(SnapshotStateObserver.kt:272)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.callOnChanged(SnapshotStateObserver.kt:215)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.access$callOnChanged(SnapshotStateObserver.kt:24)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1$2.invoke(SnapshotStateObserver.kt:43)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1$2.invoke(SnapshotStateObserver.kt:42)
at androidx.compose.ui.platform.AndroidComposeView$snapshotObserver$1.invoke(AndroidComposeView.android.kt:268)
at androidx.compose.ui.platform.AndroidComposeView$snapshotObserver$1.invoke(AndroidComposeView.android.kt:266)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke(SnapshotStateObserver.kt:42)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke(SnapshotStateObserver.kt:26)
at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot(Snapshot.kt:1446)
at androidx.compose.runtime.snapshots.SnapshotKt.takeNewSnapshot(Snapshot.kt:1456)
at androidx.compose.runtime.snapshots.SnapshotKt.access$takeNewSnapshot(Snapshot.kt:1)
at androidx.compose.runtime.snapshots.GlobalSnapshot.takeNestedSnapshot(Snapshot.kt:1132)
at androidx.compose.runtime.snapshots.Snapshot$Companion.takeSnapshot(Snapshot.kt:230)
at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invokeSuspend(SnapshotFlow.kt:150)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.flow.internal.SafeCollector.invokeSuspend(SafeCollector.kt:41)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
No exception happens if I use scrollToItem(idx)
. I tried to reproduce the issue in a sample app, but was not able to. I also wasn't able to pinpoint what exact line of code causes the issue. My best guess is that it might be caused by the icons. Each of them is received as a flow similar to this:
@Composable
private fun MyIcon() {
val image by remember { getImageFlowSomhow() }.collectAsState(initial = null)
image?.iconName?.let { iconName ->
Image(
rememberVectorPainter(image = Icons.Default.PlayArrow), // to be replaced with real icon
contentDescription = "",
Modifier
.size(32.dp)
.clickable { Log.e("tag", "MyIcon() ... clicked") }
)
}
}
Notes:
- removing the flow and image null check fixes the issue
- keeping the flow, but removing the clickable{}
also fixes the issue
Since there is more than one fix for the issue and flows are supposed to work as far as i know, my question: what could be the root cause for this exception? How can a compose node end up with no parent?Ian Lake
01/19/2022, 4:13 AMlet
? I.e., just using a local variable and an if
check? There's been a few other threads I've seen about lets being a problem recentlySimon Stahl
01/19/2022, 4:22 AMIan Lake
01/19/2022, 5:43 AMAndrey Kulikov
01/19/2022, 4:16 PMSimon Stahl
01/19/2022, 6:35 PM1.1.0-beta03
to 1.1.0-rc01
and the issue is gone.Andrey Kulikov
01/19/2022, 6:44 PM