Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LazyVerticalGrid Fresco scroll crash #132

Closed
andreas-umbricht opened this issue Jun 13, 2022 · 5 comments
Closed

LazyVerticalGrid Fresco scroll crash #132

andreas-umbricht opened this issue Jun 13, 2022 · 5 comments

Comments

@andreas-umbricht
Copy link

  • Library Version com.github.skydoves:landscapist-fresco:1.5.2
  • Affected Device: Google Pixel 4a (Android 12)
  • Not Reproducable: Huawei P30 Pro (Android 11)
  • target & compile Sdk: 31
  • compose version: 1.2.0-beta02

Describe the Bug:

When using a LazyVerticalGrid with following minimal example, the app crashes upon scrolling, when using more than 30+ image Items.
I can't reproduce the crash with my Huawei P30 Pro which runs Android 11, so it could also be a Android 12 kind of problem. But even when I test on my Huawei P30 Pro device, the pictures, which are really not that big, are loaded very slowly.

@Composable
fun GalleryScreen(navController: NavController, imageUrls: List<String>?) {
    if (i == null) return

    LazyVerticalGrid(
        columns = GridCells.Fixed(3)) {
        items(imageUrls) { imageUrl ->
            Box(modifier = Modifier.aspectRatio(1f)) {
                FrescoImage(
                    imageUrl = imageUrl,
                    contentScale = ContentScale.Crop
                )
            }
        }
    }
}

Error message is:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: app.festiguide, PID: 7549
    java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@8a09c7c
        at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:74)
        at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:263)
        at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
        at androidx.compose.ui.graphics.AndroidCanvas.drawImageRect-HPBpro0(AndroidCanvas.android.kt:271)
        at androidx.compose.ui.graphics.drawscope.CanvasDrawScope.drawImage-AZ2fEMs(CanvasDrawScope.kt:263)
        at androidx.compose.ui.node.LayoutNodeDrawScope.drawImage-AZ2fEMs(Unknown Source:39)
        at androidx.compose.ui.graphics.drawscope.DrawScope$DefaultImpls.drawImage-AZ2fEMs$default(DrawScope.kt:508)
        at androidx.compose.ui.graphics.painter.BitmapPainter.onDraw(BitmapPainter.kt:93)
        at androidx.compose.ui.graphics.painter.Painter.draw-x_KDEd0(Painter.kt:212)
        at androidx.compose.ui.draw.PainterModifier.draw(PainterModifier.kt:281)
        at androidx.compose.ui.node.DrawEntity.draw(DrawEntity.kt:98)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:316)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:306)
        at androidx.compose.ui.node.ModifiedLayoutNode.performDraw(ModifiedLayoutNode.kt:139)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:314)
        at androidx.compose.ui.node.LayoutNodeWrapper.access$drawContainedDrawModifiers(LayoutNodeWrapper.kt:60)
        at androidx.compose.ui.node.LayoutNodeWrapper$invoke$1.invoke(LayoutNodeWrapper.kt:336)
        at androidx.compose.ui.node.LayoutNodeWrapper$invoke$1.invoke(LayoutNodeWrapper.kt:335)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.LayoutNodeWrapper.invoke(LayoutNodeWrapper.kt:335)
        at androidx.compose.ui.node.LayoutNodeWrapper.invoke(LayoutNodeWrapper.kt:60)
        at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:180)
        at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:297)
        at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:238)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:301)
        at androidx.compose.ui.node.ModifiedLayoutNode.performDraw(ModifiedLayoutNode.kt:139)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:314)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:306)
        at androidx.compose.ui.node.ModifiedLayoutNode.performDraw(ModifiedLayoutNode.kt:139)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:314)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:306)
        at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:831)
        at androidx.compose.ui.node.InnerPlaceable.performDraw(InnerPlaceable.kt:90)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:314)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:306)
        at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:831)
        at androidx.compose.ui.node.InnerPlaceable.performDraw(InnerPlaceable.kt:90)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:314)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:306)
        at androidx.compose.ui.node.ModifiedLayoutNode.performDraw(ModifiedLayoutNode.kt:139)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:314)
        at androidx.compose.ui.node.LayoutNodeWrapper.access$drawContainedDrawModifiers(LayoutNodeWrapper.kt:60)
        at androidx.compose.ui.node.LayoutNodeWrapper$invoke$1.invoke(LayoutNodeWrapper.kt:336)
        at androidx.compose.ui.node.LayoutNodeWrapper$invoke$1.invoke(LayoutNodeWrapper.kt:335)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.LayoutNodeWrapper.invoke(LayoutNodeWrapper.kt:335)
        at androidx.compose.ui.node.LayoutNodeWrapper.invoke(LayoutNodeWrapper.kt:60)
        at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:180)
        at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:297)
        at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:238)
        at androidx.compose.ui.node.LayoutNodeWrapper.draw(LayoutNodeWrapper.kt:301)
        at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:831)
        at androidx.compose.ui.node.InnerPlaceable.performDraw(InnerPlaceable.kt:90)
        at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:48)
        at androidx.compose.foundation.gestures.DrawOverScrollModifier.draw(AndroidOverScroll.kt:75)
        at androidx.compose.ui.node.DrawEntity.draw(DrawEntity.kt:98)
        at androidx.compose.ui.node.LayoutNodeWrapper.drawContainedDrawModifiers(LayoutNodeWrapper.kt:316)
        at androidx.compose.ui.node.LayoutNodeWrapper.access$drawContainedDrawModifiers(LayoutNodeWrapper.kt:60)
        at androidx.compose.ui.node.LayoutNodeWrapper$invoke$1.invoke(LayoutNodeWrapper.kt:336)
        at androidx.compose.ui.node.LayoutNodeWrapper$invoke$1.invoke(LayoutNodeWrapper.kt:335)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2098)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:112)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:78)
        at androidx.compose.ui.node.LayoutNodeWrapper.invoke(LayoutNodeWrapper.kt:335)
        at androidx.compose.ui.node.LayoutNodeWrapper.invoke(LayoutNodeWrapper.kt:60)
        at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:180)
        at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:297)
        at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:948)
        at android.view.View.draw(View.java:22707)
        at android.view.View.updateDisplayListIfDirty(View.java:21579)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4512)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4485)
        at android.view.View.updateDisplayListIfDirty(View.java:21535)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4512)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4485)
        at android.view.View.updateDisplayListIfDirty(View.java:21535)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4512)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4485)
        at android.view.View.updateDisplayListIfDirty(View.java:21535)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4512)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4485)
        at android.view.View.updateDisplayListIfDirty(View.java:21535)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:534)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:540)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:616)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:4525)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4245)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3374)
E/AndroidRuntime:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2179)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8787)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037)
        at android.view.Choreographer.doCallbacks(Choreographer.java:845)
        at android.view.Choreographer.doFrame(Choreographer.java:780)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
        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:7870)
        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)

To facilitate reproducing the error you can use the following images.

            listOf(
                "https://live.staticflickr.com/65535/52140374025_d4f6fbbb61_z.jpg",
                "https://live.staticflickr.com/65535/52115578994_31a9d3f9d4_z.jpg",
                "https://live.staticflickr.com/65535/52115842270_a8083c1a31_z.jpg",
                "https://live.staticflickr.com/65535/52115842105_2449d96d93_z.jpg",
                "https://live.staticflickr.com/65535/52115578264_38a35faa82_z.jpg",
                "https://live.staticflickr.com/65535/52115332496_e3be093187_z.jpg",
                "https://live.staticflickr.com/65535/52114308052_7d47e89981_z.jpg",
                "https://live.staticflickr.com/65535/52115840490_72571bbaa8_z.jpg",
                "https://live.staticflickr.com/65535/52115840220_46a94fdb1a_z.jpg",
                "https://live.staticflickr.com/65535/52115840005_385b248a30_z.jpg",

                "https://live.staticflickr.com/65535/52115330526_72373e8750_z.jpg",
                "https://live.staticflickr.com/65535/52115371733_d363ef5a9a_z.jpg",
                "https://live.staticflickr.com/65535/52115839350_908cde3ac8_z.jpg",
                "https://live.staticflickr.com/65535/52115373383_f0f534b1e3_z.jpg",
                "https://live.staticflickr.com/65535/52115577404_0902caf6d4_z.jpg",
                "https://live.staticflickr.com/65535/52115840715_8d77dbda48_z.jpg",
                "https://live.staticflickr.com/65535/52114305022_8a55b5b037_z.jpg",
                "https://live.staticflickr.com/65535/52114304832_2e322f70cd_z.jpg",
                "https://live.staticflickr.com/65535/52115328916_59a10be33e_z.jpg",
                "https://live.staticflickr.com/65535/52114304502_a397e38038_z.jpg",

                "https://live.staticflickr.com/65535/52121460286_aa7cb20e1d_z.jpg",
                "https://live.staticflickr.com/65535/52121490528_fbbb1e0aa6_z.jpg",
                "https://live.staticflickr.com/65535/52121959385_ab62aecccb_z.jpg",
                "https://live.staticflickr.com/65535/52121959350_871200e394_z.jpg",
                "https://live.staticflickr.com/65535/52121705619_b0ea6ce267_z.jpg",
                "https://live.staticflickr.com/65535/52121959265_d642b29314_z.jpg",
                "https://live.staticflickr.com/65535/52121959205_75acaa67b0_z.jpg",
                "https://live.staticflickr.com/65535/52121490263_a4d3ea603f_z.jpg",
                "https://live.staticflickr.com/65535/52121490208_22d31dcba9_z.jpg",
                "https://live.staticflickr.com/65535/52121459831_3baeb07703_z.jpg",

                "https://live.staticflickr.com/65535/52121490113_d8e5c9a9b2_z.jpg",
                "https://live.staticflickr.com/65535/52121958980_d8f5eaa067_z.jpg",
                "https://live.staticflickr.com/65535/52121958945_c5818b15e2_z.jpg",
                "https://live.staticflickr.com/65535/52121705284_6a8e5ceba1_z.jpg",
                "https://live.staticflickr.com/65535/52121459606_2ebf4b9939_z.jpg",
                "https://live.staticflickr.com/65535/52121958815_7466a5489d_z.jpg",
                "https://live.staticflickr.com/65535/52121459501_c433bd01d6_z.jpg",
                "https://live.staticflickr.com/65535/52120425527_c8b93f0e39_z.jpg",
                "https://live.staticflickr.com/65535/52121958660_3c84e93a7c_z.jpg",
                "https://live.staticflickr.com/65535/52120425482_dd4e5a234c_z.jpg",
            )

Expected Behavior:

When I use LazyColumn instead of LazyVerticalGrid everything works fine, so I expect a similar behavior just like when I use LazyColumn.
Generally the photos are loaded much slower within a LazyVerticalGrid than in a LazyColumn.

    LazyColumn {
        items(imageUrls.value) { imageUrl ->
            Box(modifier = Modifier.aspectRatio(1f)) {
                FrescoImage(
                    imageUrl = imageUrl,
                    contentScale = ContentScale.Crop,
                    placeHolder = ImageBitmap.imageResource(R.drawable.img_placeholder_gallery)
                )
            }
        }
    }

I hope you can understand and reproduce my problem.
If you need any more information, just ask.

@skydoves
Copy link
Owner

Hi, thank you for describing the details.

I have two questions below:

  • Does the same issue happen if you use the 1.5.3-SNAPSHOT?
  • Does the same issue happen if you use GlideImage or CoilImage?

Thanks!

@andreas-umbricht
Copy link
Author

When I use the same example with com.github.skydoves:landscapist-glide:1.5.2 everything works as expected. Thanks for the hint!

LazyVerticalGrid(
        columns = GridCells.Fixed(3)) {
        items(imageUrls.value) { imageUrl ->
            Box(modifier = Modifier.aspectRatio(1f)) {
                GlideImage(
                    imageModel = imageUrl,
                    contentScale = ContentScale.Crop
                )
            }
        }
    }

When I use the example with com.github.skydoves:landscapist-coil:1.5.2 it also takes forever to load the images, or they don't get loaded at all. At least it doesn't crash unlike Fresco.

Sadly, I wasn't able to test 1.5.3-SNAPSHOT. I tried implementation "com.github.skydoves:landscapist-fresco:1.5.3-SNAPSHOT". But all I get is Could not find com.github.skydoves:landscapist-fresco:1.5.3-SNAPSHOT. when trying to build the app.

If you can help me to get 1.5.3-SNAPSHOT working I will gladly also test Fresco, Coil and Glide with that. Until then, I will simply use Glide.

@skydoves
Copy link
Owner

Thank you for checking this!
You should add the repository URL below in your gradle.build file:

repositories {
   maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

You can see the instruction here: https://github.com/skydoves/landscapist#snapshot

@andreas-umbricht
Copy link
Author

Ah, silly me. Thanks for the instruction.
Using 1.5.3-SNAPSHOT, Fresco does not crash anymore luckily, but Fresco and Coil still don't load all images or it takes ages to do so.
I think, I will stick with Glide for the moment.

@skydoves
Copy link
Owner

Thanks for checking the details.
It seems a library issue for the Coil and Fresco, but let me debug the details and keep you updated on this. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants