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

[regression/8.0.0-preview.5.8529] Crash on scrolling collection view #18834

Open
MissedSte4k opened this issue Nov 17, 2023 · 29 comments
Open

[regression/8.0.0-preview.5.8529] Crash on scrolling collection view #18834

MissedSte4k opened this issue Nov 17, 2023 · 29 comments
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView area-controls-image Image control delighter-sc has-workaround high It doesn't work at all, crashes or has a big impact. i/regression This issue described a confirmed regression on a currently supported version platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Milestone

Comments

@MissedSte4k
Copy link

MissedSte4k commented Nov 17, 2023

Description

App just crashes with Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4b0165b'
Seems like the same issue as before. This should be solved here, but in every 8.0.* revision it seems to still be crashing (and I've tried them all).

Here is the call stack. It always seems to be the same. The very odd thing in it is the reference to net7.0/JniEnvironment.g.cs. As the version I'm runing the app is .net8 ¯_(ツ)_/¯
image

Steps to Reproduce

  1. open my repository in github (it has some redundant parts from testing over issues, but does the job)
  2. run on android emulator
  3. wait for a minute until it crashes (try to stay on the top of the page, so new images appear and push over images down)

Expected behavior: images open up and older images are pushed down

Actual behavior: images open up and older images are pushed down, but after about a minute you experience a crash with Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4b0165b

P.S. for anyone that might launch the app on windows and see the insane behavior of DataTemplates - I already reported it here, over a year back.

Link to public reproduction project repository

https://github.com/MissedSte4k/MAUI-Canvas-trying-to-use-a-recycled-bitmap-crash-sample

Version with bug

8.0.0-preview.5.8529

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

8.0.0-preview.4.8333

Affected platforms

Android

Affected platform versions

No response

Did you find any workaround?

Nope. Tried everything referenced in issues that got solved in #12310, but to no avail.

Relevant log output

No response

@MissedSte4k MissedSte4k added the t/bug Something isn't working label Nov 17, 2023
@ghost ghost added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Nov 17, 2023
@samhouts samhouts added the potential-regression This issue described a possible regression on a currently supported version., verification pending label Dec 6, 2023
@Engisan
Copy link

Engisan commented Dec 7, 2023

Same here :/ I had to wait with releasing of my app due to huge issues in .net7
These were fixed in .net8 but now I am stopped at this one :/ so I cannot release my app to my customers again... No workaround works for me.

@samhouts samhouts added the high It doesn't work at all, crashes or has a big impact. label Dec 7, 2023
@samhouts samhouts changed the title Crash on scrolling collection view [regression/8.0.3] Crash on scrolling collection view Dec 7, 2023
@XamlTest XamlTest added s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed labels Dec 8, 2023
@XamlTest
Copy link

XamlTest commented Dec 8, 2023

Verified this on Visual Studio Enterprise 17.9.0 Preview 1(8.0.3). Repro on Android 14.0-API34 and Windows 11, not repro on iOS 17.0 and MacCatalyst with below Project:
TestImages.zip

@Stefan171086
Copy link

Stefan171086 commented Jan 5, 2024

@samhouts: what is the status on this issue? We experiencing the same crashes and this is preventing us releasing an urgent update to our customers!

Update after looking at similar issues and try/error:
Workaround in #13534 did the job for me. Setting a fix height on an image in this case was not that what I wanted, but it prevents from crashes and unsatisfied customers.

Hope this helps solving this issue again! BR Stefan

@stoff99
Copy link

stoff99 commented Feb 13, 2024

Same here,

we get the same crashes in our public app right now with couple of devices.
We have a simple screen to collect photos with the device camera and place this images into a horizontal scrolling collection view.

We see the same error as above:
Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* ) Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualBooleanMethod(String , IJavaPeerable , JniArgumentValue* ) Android.Views.ViewGroup.DrawChild(Canvas , View , Int64 ) Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.DrawChild(Canvas canvas, View child, Int64 drawingTime) Android.Views.ViewGroup.n_DrawChild_Landroid_graphics_Canvas_Landroid_view_View_J(IntPtr jnienv, IntPtr native__this, IntPtr native_canvas, IntPtr native_child, Int64 drawingTime) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLLJ_Z(_JniMarshal_PPLLJ_Z callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, IntPtr p1, Int64 p2) com.microsoft.maui.PlatformContentViewGroup.dispatchDraw PlatformContentViewGroup.java:47 android.view.View.draw View.java:25151 androidx.recyclerview.widget.RecyclerView.drawChild RecyclerView.java:5499 android.view.ViewGroup.dispatchDraw ViewGroup.java:4534 androidx.recyclerview.widget.RecyclerView.draw RecyclerView.java:4898 android.view.View.updateDisplayListIfDirty View.java:24007 androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild CoordinatorLayout.java:1312 android.view.ViewGroup.dispatchDraw ViewGroup.java:4534 androidx.drawerlayout.widget.DrawerLayout.drawChild DrawerLayout.java:1483 crc640ec207abc449b2ca.ShellFlyoutRenderer.n_drawChild(Native Method) crc640ec207abc449b2ca.ShellFlyoutRenderer.drawChild ShellFlyoutRenderer.java:57 android.view.ViewGroup.dispatchDraw ViewGroup.java:4534

@stoff99
Copy link

stoff99 commented Feb 23, 2024

@mauiteam Is there any update about this?
I released now 5 Android updates the last 7 days with workarounds but i still see this crash happen in app center.
Also in the crash report i have to information where this happens.
Is there anything how i can find out more to see better error logs in AppCenter for Android?

@Simoo23
Copy link

Simoo23 commented Mar 21, 2024

Same issue with .NET 8.
I have a CollectionView with images, if you scroll the list the app will crash.
I didn't find any workaround.

@jing8956
Copy link

jing8956 commented Apr 1, 2024

When I replace the default StreamImageSourceService with the following code. Scroll through the CollectionView quickly and the program never crash again.

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .ConfigureImageSources(services =>
            {
#if ANDROID
                services.RemoveAll<IImageSourceService<IStreamImageSource>>();
                services.RemoveAll<IImageSourceService<StreamImageSource>>();
                services.AddService<IStreamImageSource>(_ => new CustomStreamImageSourceService());
                services.AddService<StreamImageSource>(_ => new CustomStreamImageSourceService());
#endif
            });

#if DEBUG
		builder.Logging.AddDebug();
#endif

        return builder.Build();
    }

#if ANDROID

    public class CustomStreamImageSourceService : StreamImageSourceService
    {
        public override async Task<IImageSourceServiceResult?> LoadDrawableAsync(IImageSource imageSource, ImageView imageView, CancellationToken cancellationToken = default)
        {
            var result = await base.GetDrawableAsync(imageSource, imageView.Context!, cancellationToken);
            // if (result?.Value is BitmapDrawable drawable && drawable.Bitmap?.IsRecycled == true)
            // {
            //     drawable.Bitmap.IsRecycled always false.
            // }
            imageView.SetImageDrawable(result?.Value);
            return result;
        }
    }

#endif

}

It might be base.LoadDrawableAsync passes a recycled bitmap to imageView, causing the program to crash.
The same may be required for both FileImageSource and UriImageSource.
(Machine translation was used)

@plppp2001
Copy link

plppp2001 commented Apr 4, 2024

I'm getting this error when I have an Image on my CarouselView . This is a show stopper for me.

I'm using: Net 8 MAUI - Latest VS2022 == Version 17.9.5

	<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.14" />
	<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.14" />

image

@switchyy
Copy link

switchyy commented Apr 8, 2024

I have the same issue with the latest VS version and .NET 8.
image
I'm receiving the images through an API call from a FileManager, and the image is located inside grid, it crashed the app very rarely.
I can offer more info if needed.

@lythix
Copy link

lythix commented Apr 10, 2024

Chiming in here with my 2c worth of evidence. I'm getting same issue with dotnet 8.0 (8.0.3) and VS 2022 Version 17.9.5
(Android app)

2024-04-10 09:35:54.868 +08:00 [FTL] Java.Lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@fe28425
   at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args)
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualBooleanMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters)
   at Android.Views.ViewGroup.DrawChild(Canvas canvas, View child, Int64 drawingTime)
   at Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.DrawChild(Canvas canvas, View child, Int64 drawingTime)
   at Android.Views.ViewGroup.n_DrawChild_Landroid_graphics_Canvas_Landroid_view_View_J(IntPtr jnienv, IntPtr native__this, IntPtr native_canvas, IntPtr native_child, Int64 drawingTime)
   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLLJ_Z(_JniMarshal_PPLLJ_Z callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, IntPtr p1, Int64 p2)

I'm rather glad I found my way to this issue, I thought I was doing something wrong.

@samhouts samhouts changed the title [regression/8.0.3] Crash on scrolling collection view [regression/8.0.0-preview.5.8529] Crash on scrolling collection view Apr 12, 2024
@samhouts samhouts added i/regression This issue described a confirmed regression on a currently supported version area-controls-image Image control and removed potential-regression This issue described a possible regression on a currently supported version., verification pending legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor labels Apr 12, 2024
@dotnet-policy-service dotnet-policy-service bot added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Apr 12, 2024
@samhouts
Copy link
Member

Confirmed that this regressed between 8.0.0-preview.4.8333 and 8.0.0-preview.5.8529. Before pre5, the scrolling performance was atrocious, so I assume this was a memory leak resolved by properly disposing of the images. However, that leads to this crash.

Not sure exactly what the culprit was, but #14933, #12011, and #14109 seem most sus.

Incidentally, I changed the Frame to a Border to see if it helped and with that, I see that the background color of the cell goes from white in pre4 to black in pre5, which seems to be related to #14933 and is probably another regression/behavior change.

@samhouts
Copy link
Member

Oh, yep, the repro is using a DTS, so looks like #12011 is most likely. @Redth fyi

@Redth Redth added this to the Backlog milestone May 6, 2024
@H-A-Hristov
Copy link

H-A-Hristov commented May 8, 2024

I have seen this before.
Not specifying the Height and Width request, in your ImageViews, (using URLs of uploaded pictures with 1000x1600 for example as source) that are contained in your CollectionView, lead to the following problems:

In Android:
You get random runtime crashes, when you scroll down the collection view.
In IOS:
You get empty collection view the first time you enter the page. Collection view with only first item loaded the second time you enter the page. And full collection view when you enter 3rd time in the page.

Setting WidthRequest=100, HeightRequest=100 is quick way to check if this applies to you.

(Forgot to say that this IOS behavior does not repeat when you close and open the app (it seems caching is involved in making the problem resolve itself), only reinstall introduces it again. But on Android it is persistent.)

@lythix
Copy link

lythix commented May 9, 2024

Thanks for the reply!

Setting WidthRequest=100, HeightRequest=100 is quick way to check if this applies to you.

Meaning the crashing stops? I've wondered if perhaps I can set or bind the height/width request to a calculated value so it is provided (but still fills the available width/height but stops the crashes)

@H-A-Hristov
Copy link

H-A-Hristov commented May 9, 2024

Meaning the crashing stops? I've wondered if perhaps I can set or bind the height/width request to a calculated value so it is provided (but still fills the available width/height but stops the crashes)

Not only the android crashing. The weird behavior on IOS also.
You open "details" page, that contains CollectionView, that has ItemTeplate of DataTemplate of Image.
Nothing else. And on the Image you have set "MaximumWidthRequest" and "MaximumHeightRequest", with aspect set to Fit.
Open details once - empty.
Second - only one image showing.
Third time - everything.

Set specific measurements and both problems are gone.

To make matter worse - on the device I develop with most of the time, this problem could not be reproduced.
On one of the test devices, this problem was showing, but only if your list has set amount of items. 4 or 5 pages - no problem.
And the key to find this out was another test device, that was throwing this exception (crashing, actually), the second you try to scroll.

I hope this saves you some time.

@Eilon Eilon removed the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label May 10, 2024
@Simoo23
Copy link

Simoo23 commented May 15, 2024

Any news on this? This issue is still presenting with maui 8.0.40.
I'm not using an itemTemplateSelector in my case, just a collectionview where every item of the list is a grid with an image and labels.
Set fixed Width and Height is not working

@Simoo23
Copy link

Simoo23 commented May 16, 2024

When I replace the default StreamImageSourceService with the following code. Scroll through the CollectionView quickly and the program never crash again.

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .ConfigureImageSources(services =>
            {
#if ANDROID
                services.RemoveAll<IImageSourceService<IStreamImageSource>>();
                services.RemoveAll<IImageSourceService<StreamImageSource>>();
                services.AddService<IStreamImageSource>(_ => new CustomStreamImageSourceService());
                services.AddService<StreamImageSource>(_ => new CustomStreamImageSourceService());
#endif
            });

#if DEBUG
		builder.Logging.AddDebug();
#endif

        return builder.Build();
    }

#if ANDROID

    public class CustomStreamImageSourceService : StreamImageSourceService
    {
        public override async Task<IImageSourceServiceResult?> LoadDrawableAsync(IImageSource imageSource, ImageView imageView, CancellationToken cancellationToken = default)
        {
            var result = await base.GetDrawableAsync(imageSource, imageView.Context!, cancellationToken);
            // if (result?.Value is BitmapDrawable drawable && drawable.Bitmap?.IsRecycled == true)
            // {
            //     drawable.Bitmap.IsRecycled always false.
            // }
            imageView.SetImageDrawable(result?.Value);
            return result;
        }
    }

#endif

}

It might be base.LoadDrawableAsync passes a recycled bitmap to imageView, causing the program to crash. The same may be required for both FileImageSource and UriImageSource. (Machine translation was used)

From my tests this resolve the problem

@samhouts
Copy link
Member

I ran into this one again on my own app when I decided to remove the WidthRequest from my images. Setting an explicit WidthRequest and HeightRequest is certainly the workaround.

@viktorszekeress
Copy link

@samhouts I've observed that WidthRequest technique works only under certain circumstances. I create a sample app to repro the issue.
App has a simple timer that periodically updates Image.Source. On my real devices (Galaxy A52s, Galaxy S22), it crashes with an update period of 70ms. There are 2 buttons to increase/decrease the delay.

Interestingly, if Image.WidthRequest is 500, then it crashes. If I change WidthRequest to 400 or lower, then it doesn't crash.

MauiAppRecycledBitmap.zip

@Simoo23
Copy link

Simoo23 commented Jun 12, 2024

@viktorszekeress Did you try if this workaround work for you?

For me it seems to work

When I replace the default StreamImageSourceService with the following code. Scroll through the CollectionView quickly and the program never crash again.

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .ConfigureImageSources(services =>
            {
#if ANDROID
                services.RemoveAll<IImageSourceService<IStreamImageSource>>();
                services.RemoveAll<IImageSourceService<StreamImageSource>>();
                services.AddService<IStreamImageSource>(_ => new CustomStreamImageSourceService());
                services.AddService<StreamImageSource>(_ => new CustomStreamImageSourceService());
#endif
            });

#if DEBUG
		builder.Logging.AddDebug();
#endif

        return builder.Build();
    }

#if ANDROID

    public class CustomStreamImageSourceService : StreamImageSourceService
    {
        public override async Task<IImageSourceServiceResult?> LoadDrawableAsync(IImageSource imageSource, ImageView imageView, CancellationToken cancellationToken = default)
        {
            var result = await base.GetDrawableAsync(imageSource, imageView.Context!, cancellationToken);
            // if (result?.Value is BitmapDrawable drawable && drawable.Bitmap?.IsRecycled == true)
            // {
            //     drawable.Bitmap.IsRecycled always false.
            // }
            imageView.SetImageDrawable(result?.Value);
            return result;
        }
    }

#endif

}

It might be base.LoadDrawableAsync passes a recycled bitmap to imageView, causing the program to crash. The same may be required for both FileImageSource and UriImageSource. (Machine translation was used)

@viktorszekeress
Copy link

@Simoo23 I tried that and it does indeed solve the original problem - application doesn't crash now. The new problem is that RAM usage skyrockets for me to 2+GB. I have a CollectionView with potentially 200+ images (loaded on demand).

I also noticed decreased performance with this solution.

What I eventually did is that instead of converting byte[] to ImageSource I convert byte[] to Image - meaning it creates whole new Image for each byte[]. This does also increase RAM usage a bit (100 MB), but from my testing it settles down after a while and seems to behave stable.

@Simoo23
Copy link

Simoo23 commented Jun 12, 2024

@viktorszekeress I'll try to check the Ram usage too.

But how do you convert byte[] to Image and bind to Image component in MVVM without using ImageSource?

@viktorszekeress
Copy link

@Simoo23 Instead of using Image in XAML and binding ImageSource, I use ContentView and I bind Content to byte[].

@plppp2001
Copy link

@Simoo23 Instead of using Image in XAML and binding ImageSource, I use ContentView and I bind Content to byte[].

Does this work flawlessly on both iOS and ANdroid?

Also, what if we need to bind the image from an HTTP URI link? Any ideas there?

@viktorszekeress
Copy link

Does this work flawlessly on both iOS and ANdroid?

I haven't tested it on iOS. The question is, do we need this workaround there?

Also, what if we need to bind the image from an HTTP URI link? Any ideas there?

It's just a matter of converter (parameter) and how you construct the image.

@Simoo23
Copy link

Simoo23 commented Jun 17, 2024

Is not possibile to increase the priority of this bug?
I think that this is a basic feature as we are talking of a simple list of images and this bug is opened from Nov 17, 2023.
We have some workarounds but they all have problems

@H-A-Hristov
Copy link

Interestingly, if Image.WidthRequest is 500, then it crashes. If I change WidthRequest to 400 or lower, then it doesn't crash.

Are you sure about this? I cannot say about "width", but I am using "HeightRequest" of 500 and above, without this issue manifesting.

@viktorszekeress
Copy link

viktorszekeress commented Jun 24, 2024

Are you sure about this? I cannot say about "width", but I am using "HeightRequest" of 500 and above, without this issue manifesting.

I'm sure. Obviously, it depends on other circumstances, like: original size of the image, aspect ratio, available area...
Just try out the sample I provided.

@KaoutharG
Copy link

Hi every one,
i have the same issue when scrolling a collection view: Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@a06a0c7' even after writing the code i found here:
`using Microsoft.Extensions.DependencyInjection.Extensions;
#if ANDROID
using Android.Widget;
using Android.Graphics.Drawables; // Pour BitmapDrawable
#endif
public static class MauiProgram
{
public static IServiceProvider ServiceProvider;
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
fonts.AddFont("Roboto-Meduim.ttf", "RobotoM");
fonts.AddFont("Roboto-Regular.ttf", "RobotoR");
})
.ConfigureImageSources(services =>
{
#if ANDROID
services.RemoveAll<IImageSourceService>();
services.RemoveAll<IImageSourceService>();
services.AddService(_ => new CustomStreamImageSourceService());
services.AddService(_ => new CustomStreamImageSourceService());
#endif
#if DEBUG
builder.Logging.AddDebug();
#endif
//this lines for eviting this error: Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap'

        var app = builder.Build();
        ServiceProvider = app.Services;
        return app;

    }

#if ANDROID

    public class CustomStreamImageSourceService : StreamImageSourceService
    {
        public override async Task<IImageSourceServiceResult?> LoadDrawableAsync(IImageSource imageSource, ImageView imageView, CancellationToken cancellationToken = default)
        {
            var result = await base.GetDrawableAsync(imageSource, imageView.Context!, cancellationToken);
            // if (result?.Value is BitmapDrawable drawable && drawable.Bitmap?.IsRecycled == true)
            // {
            //     drawable.Bitmap.IsRecycled always false.
            // }
            imageView.SetImageDrawable(result?.Value);
            return result;
        }
    }

#endif
}i'm using image with width 160 only : like here :` but it crashes. Can any one help me ? Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView area-controls-image Image control delighter-sc has-workaround high It doesn't work at all, crashes or has a big impact. i/regression This issue described a confirmed regression on a currently supported version platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Projects
Status: Todo
Development

No branches or pull requests