android/sunflower

App Crash when scroll down in Gallery Screen

HieuNguyennd96 opened this issue · 2 comments

When I scroll down in Gallery screen, app is crashed immediately
Device: Pixel 2XL
Android Version 11
Log:
FATAL EXCEPTION: main
Process: com.google.samples.apps.sunflower, PID: 17655
java.lang.IllegalArgumentException: Key 8Jau7nWrgmE was already used. If you are using LazyColumn/Row please make sure you provide a unique key for each item.
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:411)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:733)
at androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScopeImpl.measure-0kLqBqw(LazyLayoutMeasureScope.kt:118)
at androidx.compose.foundation.lazy.grid.LazyMeasuredItemProvider.getAndMeasure-ednRnyU(LazyMeasuredItemProvider.kt:44)
at androidx.compose.foundation.lazy.grid.LazyMeasuredLineProvider.getAndMeasure-bKFJvoY(LazyMeasuredLineProvider.kt:70)
at androidx.compose.foundation.lazy.grid.LazyGridMeasureKt.measureLazyGrid-0cYbdkg(LazyGridMeasure.kt:147)
at androidx.compose.foundation.lazy.grid.LazyGridKt$rememberLazyGridMeasurePolicy$1$1.invoke-0kLqBqw(LazyGrid.kt:329)
at androidx.compose.foundation.lazy.grid.LazyGridKt$rememberLazyGridMeasurePolicy$1$1.invoke(LazyGrid.kt:179)
at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$1$2$1.invoke-0kLqBqw(LazyLayout.kt:71)
at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$1$2$1.invoke(LazyLayout.kt:69)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:591)
at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103)
at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:580)
at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
at androidx.compose.foundation.layout.PaddingValuesModifier.measure-3p2s80s(Padding.kt:417)
at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1090)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1086)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2139)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:130)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:126)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:126)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:107)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1086)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:342)
at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1122)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:307)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout-0kLqBqw(MeasureAndLayoutDelegate.kt:375)
2023-04-21 15:03:53.952 17655-17655 AndroidRuntime com.google.samples.apps.sunflower E at androidx.compose.ui.platform.AndroidComposeView.measureAndLayout-0kLqBqw(AndroidComposeView.android.kt:815)
at androidx.compose.ui.node.LayoutNode.forceRemeasure(LayoutNode.kt:1194)
at androidx.compose.ui.node.LayoutModifierNode.forceRemeasure(LayoutModifierNode.kt:55)
at androidx.compose.foundation.lazy.grid.LazyGridState.onScroll$foundation_release(LazyGridState.kt:298)
at androidx.compose.foundation.lazy.grid.LazyGridState$scrollableState$1.invoke(LazyGridState.kt:165)
at androidx.compose.foundation.lazy.grid.LazyGridState$scrollableState$1.invoke(LazyGridState.kt:165)
at androidx.compose.foundation.gestures.DefaultScrollableState$scrollScope$1.scrollBy(ScrollableState.kt:164)
at androidx.compose.foundation.gestures.ScrollingLogic.dispatchScroll-3eAAhYA(Scrollable.kt:376)
at androidx.compose.foundation.gestures.ScrollingLogic$doFlingAnimation$2$outerScopeScroll$1.invoke-MK-Hz9U(Scrollable.kt:464)
at androidx.compose.foundation.gestures.ScrollingLogic$doFlingAnimation$2$outerScopeScroll$1.invoke(Scrollable.kt:463)
at androidx.compose.foundation.gestures.ScrollingLogic$doFlingAnimation$2$scope$1.scrollBy(Scrollable.kt:468)
at androidx.compose.foundation.gestures.DefaultFlingBehavior$performFling$2$1.invoke(Scrollable.kt:579)
at androidx.compose.foundation.gestures.DefaultFlingBehavior$performFling$2$1.invoke(Scrollable.kt:577)
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$2.invoke(Recomposer.kt:518)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:511)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
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:970)
at android.view.Choreographer.doCallbacks(Choreographer.java:796)
at android.view.Choreographer.doFrame(Choreographer.java:727)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@13bc236, androidx.compose.runtime.BroadcastFrameClock@7625537, StandaloneCoroutine{Cancelling}@a5f3aa4, AndroidUiDispatcher@d42200d]

I found some photo?.id is duplicated. Therefore, item key isn't a unique key. I change photo?.id ?: 0 to index and it works

@Composable private fun GalleryScreen( plantPictures: Flow<PagingData<UnsplashPhoto>>, onPhotoClick: (UnsplashPhoto) -> Unit = {}, onUpClick: () -> Unit = {}, ) { Scaffold( topBar = { GalleryTopBar(onUpClick = onUpClick) }, ) { padding -> val pagingItems: LazyPagingItems<UnsplashPhoto> = plantPictures.collectAsLazyPagingItems() LazyVerticalGrid( columns = GridCells.Fixed(2), modifier = Modifier.padding(padding), contentPadding = PaddingValues(all = dimensionResource(id = R.dimen.card_side_margin)) ) { // TODO update this implementation once paging Compose supports LazyGridScope // See: https://issuetracker.google.com/issues/178087310 items( count = pagingItems.itemCount, key = { index -> val photo = pagingItems[index] index } ) { index -> val photo = pagingItems[index] ?: return@items PhotoListItem(photo = photo) { onPhotoClick(photo) } } } } }

Thanks @HieuNguyennd96 for reporting! Feel free to send us a pull request with that fix.