Change theme
Help
Press space for more information.
Show links for this issue (Shortcut: i, l)
Copy issue ID
Previous Issue (Shortcut: k)
Next Issue (Shortcut: j)
Sign in to use full features.
Vote: I am impacted
Notification menu
Refresh (Shortcut: Shift+r)
Go home (Shortcut: u)
Pending code changes (auto-populated)
View issue level access limits(Press Alt + Right arrow for more information)
Attachment actions
Unintended behavior
View staffing
Description
Version used:
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.tv:tv-foundation:1.0.0-alpha10")
implementation("androidx.tv:tv-material:1.0.0-alpha10")
implementation("androidx.navigation:navigation-compose:2.7.6")
Devices/Android versions reproduced on:
- Google TV emulator API 34 1080p
Steps to reproduce:
1. Turn on Talkback
2. Scroll up in a list with a lot of content
3. Crash
It seems to occur when there is a large amount of content to render and so far I've only reproduced it when scrolling up, not down. I've attached a basic project which reproduces the crash. For the sample project, I used LazyColumn instead of TvLazyColumn because it pages up a large amount at a time which triggers the crash. However in our own app, this crash occurs with TvLazyColumn, but in a much more complicated layout which seems sufficient to trigger the crash. So far I've only been able to reproduce the crash while inside a NavHost but I'm not sure if this is relevant.
Stack track:
FATAL EXCEPTION: main
Process: com.example.talkbackcrashreproducer, PID: 5825
java.lang.IllegalStateException: Place was called on a node which was placed already
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.onNodePlaced$ui_release(LayoutNodeLayoutDelegate.kt:1457)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.placeAt-f8xVGno(LayoutNodeLayoutDelegate.kt:1311)
at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:34)
at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer-aW-9-wM(Placeable.kt:489)
at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer-aW-9-wM$default(Placeable.kt:320)
at androidx.compose.foundation.lazy.LazyListMeasuredItem.place(LazyListMeasuredItem.kt:182)
at androidx.compose.foundation.lazy.LazyListMeasureKt$measureLazyList$8.invoke(LazyListMeasure.kt:353)
at androidx.compose.foundation.lazy.LazyListMeasureKt$measureLazyList$8.invoke(LazyListMeasure.kt:350)
at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:70)
at androidx.compose.foundation.lazy.LazyListMeasureResult.placeChildren(Unknown Source:2)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure-3p2s80s$$inlined$createMeasureResult$2.placeChildren(SubcomposeLayout.kt:951)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate$layoutChildren$1.invoke(LayoutNodeLayoutDelegate.kt:1093)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate$layoutChildren$1.invoke(LayoutNodeLayoutDelegate.kt:1088)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:496)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release(OwnerSnapshotObserver.kt:81)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release$default(OwnerSnapshotObserver.kt:75)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.layoutChildren(LayoutNodeLayoutDelegate.kt:1088)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.onNodePlaced$ui_release(LayoutNodeLayoutDelegate.kt:1470)
at androidx.compose.ui.node.InnerNodeCoordinator$LookaheadDelegateImpl.placeChildren(InnerNodeCoordinator.kt:97)
at androidx.compose.ui.node.LookaheadDelegate.placeAt-f8xVGno(LookaheadDelegate.kt:156)
at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:34)
at androidx.compose.ui.layout.Placeable$PlacementScope.place(Placeable.kt:460)
at androidx.compose.ui.layout.Placeable$PlacementScope.place$default(Placeable.kt:218)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2$1.invoke(AndroidOverscroll.kt:589)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2$1.invoke(AndroidOverscroll.kt:588)
at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:70)
at androidx.compose.ui.node.LookaheadDelegate.placeChildren(LookaheadDelegate.kt:178)
at androidx.compose.ui.node.LookaheadDelegate.placeAt-f8xVGno(LookaheadDelegate.kt:156)
at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:34)
at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer(Placeable.kt:486)
at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer$default(Placeable.kt:299)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1$1.invoke(AndroidOverscroll.kt:577)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1$1.invoke(AndroidOverscroll.kt:570)
at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:70)
at androidx.compose.ui.node.LookaheadDelegate.placeChildren(LookaheadDelegate.kt:178)
at androidx.compose.ui.node.LookaheadDelegate.placeAt-f8xVGno(LookaheadDelegate.kt:156)
at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:34)
at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer(Placeable.kt:486)
at androidx.compose.ui.layout.Placeable$PlacementScope.placeWithLayer$default(Placeable.kt:299)
at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier$measure$1.invoke(GraphicsLayerModifier.kt:648)
at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier$measure$1.invoke(GraphicsLayerModifier.kt:647)
at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:70)
at androidx.compose.ui.node.LookaheadDelegate.placeChildren(LookaheadDelegate.kt:178)
at androidx.compose.ui.node.LookaheadDelegate.placeAt-f8xVGno(LookaheadDelegate.kt:156)
at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:34)
at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:463)
at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50$default(Placeable.kt:231)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate$placeAt$1.invoke(LayoutNodeLayoutDelegate.kt:1317)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate$placeAt$1.invoke(LayoutNodeLayoutDelegate.kt:1315)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:496)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release(OwnerSnapshotObserver.kt:96)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release$default(OwnerSnapshotObserver.kt:90)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.placeAt-f8xVGno(LayoutNodeLayoutDelegate.kt:1315)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.replace(LayoutNodeLayoutDelegate.kt:1552)
at androidx.compose.ui.node.LayoutNode.lookaheadReplace$ui_release(LayoutNode.kt:926)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout-0kLqBqw(MeasureAndLayoutDelegate.kt:413)
at androidx.compose.ui.platform.AndroidComposeView.measureAndLayout-0kLqBqw(AndroidComposeView.android.kt:970)
at androidx.compose.ui.node.LayoutNode.forceRemeasure(LayoutNode.kt:1221)
at androidx.compose.foundation.lazy.LazyListState.onScroll$foundation_release(LazyListState.kt:318)
at androidx.compose.foundation.lazy.LazyListState$scrollableState$1.invoke(LazyListState.kt:179)
at androidx.compose.foundation.lazy.LazyListState$scrollableState$1.invoke(LazyListState.kt:179)
at androidx.compose.foundation.gestures.DefaultScrollableState$scrollScope$1.scrollBy(ScrollableState.kt:166)
at androidx.compose.foundation.gestures.ScrollExtensionsKt$animateScrollBy$2$1.invoke(ScrollExtensions.kt:42)
at androidx.compose.foundation.gestures.ScrollExtensionsKt$animateScrollBy$2$1.invoke(ScrollExtensions.kt:41)
at androidx.compose.animation.core.SuspendAnimationKt$animate$3.invoke(SuspendAnimation.kt:117)
at androidx.compose.animation.core.SuspendAnimationKt$animate$3.invoke(SuspendAnimation.kt:116)
at androidx.compose.animation.core.SuspendAnimationKt.doAnimationFrame(SuspendAnimation.kt:361)
at androidx.compose.animation.core.SuspendAnimationKt.doAnimationFrameWithScale(SuspendAnimation.kt:339)
at androidx.compose.animation.core.SuspendAnimationKt.access$doAnimationFrameWithScale(SuspendAnimation.kt:1)
at androidx.compose.animation.core.SuspendAnimationKt$animate$9.invoke(SuspendAnimation.kt:279)
at androidx.compose.animation.core.SuspendAnimationKt$animate$9.invoke(SuspendAnimation.kt:278)
at androidx.compose.animation.core.SuspendAnimationKt$callWithFrameNanos$2.invoke(SuspendAnimation.kt:304)
at androidx.compose.animation.core.SuspendAnimationKt$callWithFrameNanos$2.invoke(SuspendAnimation.kt:303)
at androidx.compose.runtime.BroadcastFrameClock$FrameAwaiter.resume(BroadcastFrameClock.kt:42)
at androidx.compose.runtime.BroadcastFrameClock.sendFrame(BroadcastFrameClock.kt:71)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:555)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:548)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:878)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@cc7b3b0, androidx.compose.runtime.BroadcastFrameClock@3e75229, StandaloneCoroutine{Cancelling}@93ca9ae, AndroidUiDispatcher@51b734f]
Sample code (also in zip file):
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalTvMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "root") {
navigation(startDestination = "crashdemo", route = "root") {
composable("crashdemo") { CrashDemo() }
}
}
}
}
}
@ExperimentalTvMaterial3Api
@Composable
fun CrashDemo() {
/*
Steps to reproduce:
1. Make sure Talkback is enabled
2. Scroll to the bottom of the list
3. Scroll up through the list
4. It will crash when the focus reaches the top of the screen and you press up
*/
LazyColumn {
items(30) { number ->
Button(onClick = { }) {
Text("Button $number")
}
}
}
}