glide
glide copied to clipboard
Compose crash
- version beta01
crash on HorizontalPager change page
fun PlayPageContain(
rememberHorizontalPagerState: PagerState
) {
HorizontalPager(state = rememberHorizontalPagerState) { page: Int ->
if (page == 1) {
PlayerPage(rememberHorizontalPagerState)
} else if (page == 0) {
SimplePlayingQueuePage(rememberHorizontalPagerState)
} else {
SimpleCurrentLyricsDetailPage(rememberHorizontalPagerState)
}
}
}
@Composable
fun PlayerPage(
rememberPagerState: PagerState
) {
val playerComponent by remember { mutableStateOf(PlayerComponent()) }
val song by playerComponent.model.subscribeAsState()
Column(modifier = Modifier.fillMaxSize()) {
val painter = painterResource(MR.images.default_audio_art)
Box {
GlideImage(song, modifier = Modifier.padding(top = getSafeTop()).padding(16.dp)
.fillMaxWidth().aspectRatio(1f).clip(Colors.songRoundedCornerShape),
contentDescription = null, placeholderPaint = painter)
val isBuffing by playerComponent.isBuffing.subscribeAsState()
if (isBuffing) {
CircularProgressIndicator(modifier = Modifier.width(36.dp).height(36.dp).align(
Alignment.Center
))
}
}
PlayerControlWidget(playerComponent, song, Modifier.weight(1f), rememberPagerState)
BottomMenu(playerComponent, rememberPagerState)
}
DisposableEffect(playerComponent) {
playerComponent.uiRun()
onDispose {
playerComponent.uiDispose()
}
}
}
java.lang.IllegalArgumentException: at com.bumptech.glide.util.Preconditions.checkArgument(Preconditions.java:21) at com.bumptech.glide.util.Preconditions.checkArgument(Preconditions.java:16) at com.bumptech.glide.integration.compose.GlideNode$launchRequest$1.invoke(GlideModifier.kt:404) at com.bumptech.glide.integration.compose.GlideNode$launchRequest$1.invoke(GlideModifier.kt:400) at androidx.compose.ui.platform.AndroidComposeView.onEndApplyChanges(AndroidComposeView.android.kt:694) at androidx.compose.ui.node.UiApplier.onEndChanges(UiApplier.android.kt:48) at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:822) at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849) at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1041) at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:4007) at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:4007) at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:4007) at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:721) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:694) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:685) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:669) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:1014) at androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScopeImpl.measure-0kLqBqw(LazyLayoutMeasureScope.kt:121) at androidx.compose.foundation.pager.PagerMeasureKt.getAndMeasure-SGf7dI0(PagerMeasure.kt:476) at androidx.compose.foundation.pager.PagerMeasureKt.measurePager-ntgEbfI(PagerMeasure.kt:141) at androidx.compose.foundation.pager.PagerMeasurePolicyKt$rememberPagerMeasurePolicy$1$1.invoke-0kLqBqw(PagerMeasurePolicy.kt:159) at androidx.compose.foundation.pager.PagerMeasurePolicyKt$rememberPagerMeasurePolicy$1$1.invoke(PagerMeasurePolicy.kt:66) at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$3$2$1.invoke-0kLqBqw(LazyLayout.kt:87) at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$3$2$1.invoke(LazyLayout.kt:80) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:866) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126) at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2.invoke-3p2s80s(AndroidOverscroll.kt:578) at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2.invoke(AndroidOverscroll.kt:577) at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(LayoutModifier.kt:291) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1.invoke-3p2s80s(AndroidOverscroll.kt:562) at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1.invoke(AndroidOverscroll.kt:561) at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(LayoutModifier.kt:291) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:646) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) 2023-10-09 21:00:50.984 32541-32541 AndroidRuntime com.caij.puremusic E at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2299) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:467) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1140) at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:321) at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout-0kLqBqw(MeasureAndLayoutDelegate.kt:389) at androidx.compose.ui.platform.AndroidComposeView.measureAndLayout-0kLqBqw(AndroidComposeView.android.kt:890) at androidx.compose.ui.node.LayoutNode.forceRemeasure(LayoutNode.kt:1214) at androidx.compose.foundation.pager.PagerState.performScroll(PagerState.kt:555) at androidx.compose.foundation.pager.PagerState.access$performScroll(PagerState.kt:165) at androidx.compose.foundation.pager.PagerState$scrollableState$1.invoke(PagerState.kt:203) at androidx.compose.foundation.pager.PagerState$scrollableState$1.invoke(PagerState.kt:203) at androidx.compose.foundation.gestures.DefaultScrollableState$scrollScope$1.scrollBy(ScrollableState.kt:166) at androidx.compose.foundation.gestures.ScrollingLogic$dispatchScroll$performScroll$1.invoke-MK-Hz9U(Scrollable.kt:425) at androidx.compose.foundation.gestures.ScrollingLogic$dispatchScroll$performScroll$1.invoke(Scrollable.kt:417) at androidx.compose.foundation.AndroidEdgeEffectOverscrollEffect.applyToScroll-Rhakbz0(AndroidOverscroll.kt:180) at androidx.compose.foundation.gestures.ScrollingLogic.dispatchScroll-3eAAhYA(Scrollable.kt:438) at androidx.compose.foundation.gestures.ScrollDraggableState.dragBy(Scrollable.kt:526) at androidx.compose.foundation.gestures.DraggableNode$pointerInputNode$1$1$1$1.invokeSuspend(Draggable.kt:311) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81) at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41) at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:68) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1449) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1459) at android.view.Choreographer.doCallbacks(Choreographer.java:1089) at android.view.Choreographer.doFrame(Choreographer.java:998) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1431) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:210) at android.os.Looper.loop(Looper.java:299) at android.app.ActivityThread.main(ActivityThread.java:8261) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:559)
I've tried this on an emulator and I'm not able to reproduce this crash:
val pagerState = rememberPagerState(pageCount = {
10
})
HorizontalPager(state = pagerState, modifier = Modifier.fillMaxSize(1f)) { page: Int ->
Column(modifier = Modifier.fillMaxSize(1f)) {
Box {
val model = if (page == 0) {
R.drawable.star_big_on
} else if (page == 1) {
R.drawable.star_big_off
} else if (page == 5) {
R.drawable.btn_radio
} else if (page == 6) {
R.drawable.arrow_down_float
} else {
R.drawable.button_onoff_indicator_on
}
GlideImage(model = model, contentDescription = "", modifier = Modifier.width(100.dp).height(100.dp))
}
}
}
Can you think of any tweak I should make to that code to reproduce the issue?
For now I have a speculative fix - I think nothing stops the sideEffect block from being scheduled multiple times, so that assertion should instead be an early return. It would be nice to validate that works though (and maybe add a test).
@sjudd the placeholder causes the crash, that's why you don't see it in your example.
I am currently seeing this in my app in prod. Hopefully it gets fixed soon! Thanks!
@sjudd hello , when do you plan to merge?
I am also encountering this crash issue with same stack trace (IllegalArgumentException), using LazyColumn with GlideImage, and setting a placeholder using Painter to either loading or failure
Also, need to set the LazyColumn's height to be small enough to be able to scroll through the items. The moment I scroll it crashes.
Some scenarios:
- If I don't set
loadingnorfailure, no crash when scrolling - If I set
loadingorfailuretoplaceholder(ColorDrawable(0xff0000FF.toInt())), no crash when scrolling - If I set
loadingorfaluretoplaceholder(R.drawable.ic_avatar_placeholder), no crash when scrolling - If I set
loadingorfailuretoplaceholder(painterResource(R.drawable.ic_avatar_placeholder)), it crashes when scrolling
Somehow, it doesn't like it when using Painter as placeholder.
I need to use Painter as placeholder because I created a custom Painter to draw user's initials, if their profile photo failed to load. So if user Robert Fox's avatar failed to load, the avatar will show 'RF' instead as a fallback. So I can't use static drawable resource.
I'm facing the same issue with a LazyColumn, in my case it takes a few seconds of scrolling to see the crash. Removing the painterResource and passing the resource ID directly as @iori57 suggested fixes it.
@sjudd I hit this problem much like @jorgedotcom and @iori57 using a vectorPainter for the failure placeholder. I also hit the issue only while scrolling my LazyColumn. Like them my initial workaround was to disable the use of the painter which seemed to fix the issue although it seemed like a hack.
I searched issues and found this ticket and saw that you made a fix. I tried the latest beta2 snapshot build of glide compose with my original code utilizing the vectorPainter. I'm happy to report it fixed the problem and so far everything looks good. I look forward to an official release of compose beta2.