maui icon indicating copy to clipboard operation
maui copied to clipboard

Carousel issue - Canvas: trying to use a recycled bitmap android.graphics.Bitmap

Open mehrdadab opened this issue 3 years ago • 19 comments

Description

I am using CarouselView in .Net Maui, I have four image Urls that I assign to an Image component inside a CarouselView, my code is as below:

       <CarouselView ItemsSource="{Binding CatList}" IndicatorView="indicatorView" CurrentItemChangedCommand="{Binding CarouselImageChanged}" >
            <CarouselView.ItemTemplate>
                <DataTemplate>
                    <VerticalStackLayout MinimumHeightRequest="250" MaximumHeightRequest="300" Margin="0,0,0,5" Padding="1">
                        <Image Source="{Binding ImageUrl}"  />
                    </VerticalStackLayout>

                </DataTemplate>
            </CarouselView.ItemTemplate>

        </CarouselView>
        <IndicatorView x:Name="indicatorView"
                   IndicatorColor="LightGray"
                   SelectedIndicatorColor="DarkGray"
                   HorizontalOptions="Center" />

In the first round, when I slide through images, it works perfectly but crashes in the second round after the first or second image. When I debug, it shows the exception below: Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@bb33eb5'

My images are large and if I resize them the issue may be resolved, but I believe it should be a way to disable recycling images, in case there is no way to resize them.

Steps to Reproduce

  1. Create a .net Maui app
  2. Create a Page with CarouselView and an Image Component inside it.
  3. Bind a list that contains image URLs(to be assigned to the Image source) to CarouselView(The images must be large)
  4. Run the application on an android device and swipe the images,
  5. On the second round it crashes and the exception is Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@bb33eb5'

Link to public reproduction project repository

N/A

Version with bug

6.0.400

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android Version 9 - API 28, Emulator Android 11.0 API 30

Did you find any workaround?

I noticed if I add CurrentItemChangedCommand to the CarouselView it will happen later on Emulator(Sometimes at the third round)

Relevant log output

No response

mehrdadab avatar Sep 10 '22 07:09 mehrdadab

I found out this issue happens only in Debug mode. It works fine in Release mode.

mehrdadab avatar Sep 12 '22 07:09 mehrdadab

@mattleibow @rmarinho any additional thoughts?

PureWeen avatar Sep 14 '22 18:09 PureWeen

I wonder if we just need to stop explicitly disposing images and let glide do it for us. In the image source service, we probably need to dispose when we are returning bitmap/drawable, but do nothing when loading into an image view.

mattleibow avatar Sep 15 '22 11:09 mattleibow

Could you attach a small sample where reproduce the issue?

jsuarezruiz avatar Oct 03 '22 12:10 jsuarezruiz

Same issue on Android (it works in Windows the first time only : if I go from last image to first image again, nothing happens anymore). I try to switch the background image of a page. Each second, I change the image.

Here is some basic code to reproduce the bug : on MainPage.xaml.cs private readonly string[] _images = new string[3]; private int _index = 0; private string _splashSource; public string SplashSource { get => _splashSource; set => Set(ref _splashSource, value); // you can set _splashSource and raise INPC here to replace Set } public async Task CarouselAsync(int index) { await Task.Delay(1000); _index = index == _images.Length ? 0 : index; SplashSource = _images[index]; await CarouselAsync(_index + 1); }

And in MainPage.xaml : <Image Aspect="AspectFill" Source="{Binding SplashSource}" />

nk54 avatar Oct 07 '22 10:10 nk54

I get the same using a CarouselView with an Image in the ItemTemplate. Android 13 with .NET 7 GA tooling.

Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@83fdbc8'

Here is a repro. Just scroll and scroll until it eventually happens. Usually not very long.

https://github.com/espenrl/issue-repro/tree/main/CarouselView-android-recycled-bitmap

espenrl avatar Nov 16 '22 11:11 espenrl

Same Issue here in CollectionView Java.Lang.RuntimeException: 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@44625eb'

asabbah1 avatar Nov 17 '22 19:11 asabbah1

Yep, just experienced the same issue with the CollectionView on Android. Any workarounds for now?

AmSmart avatar Nov 18 '22 22:11 AmSmart

I found out this issue happens only in Debug mode. It works fine in Release mode.

For me it occurs in release mode.

terraslate avatar Nov 21 '22 15:11 terraslate

I wonder if we just need to stop explicitly disposing images and let glide do it for us. In the image source service, we probably need to dispose when we are returning bitmap/drawable, but do nothing when loading into an image view.

https://developer.android.com/topic/performance/graphics/manage-memory

perhaps this helps

and this

https://github.com/dotnet/maui/issues/11519

Unfortunately this bug is so unpredictable in the current implementation we cannot release anything on maui to the public. it could blow up on any device at any time as we've seen on our test devices. Regards

terraslate avatar Nov 21 '22 15:11 terraslate

same here. we are about to release the app to public, but we can´t. The error randomly happens. This is really a show stopper!

FM1973 avatar Nov 22 '22 08:11 FM1973

This happens for CarouselView and CollectionView. We got our app ready and it´s pretty stable except this bug (99% of crash reports). Can someone tell me if there is a workaround? A custom image control for example? Our customer is getting nervous and so do I.

I forgot: in my case this happens primarily in release mode.

FM1973 avatar Nov 22 '22 16:11 FM1973

Example error:

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 , IntPtr , IntPtr , IntPtr , Int64 ) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLLJ_Z(_JniMarshal_PPLLJ_Z , IntPtr , IntPtr , IntPtr , IntPtr , Int64 ) java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@ea3dcdb android.graphics.BaseCanvas.throwIfCannotDraw BaseCanvas.java:87 android.graphics.RecordingCanvas.throwIfCannotDraw RecordingCanvas.java:264 android.graphics.BaseRecordingCanvas.drawBitmap BaseRecordingCanvas.java:97 android.graphics.drawable.BitmapDrawable.draw BitmapDrawable.java:560 android.widget.ImageView.onDraw ImageView.java:1462 android.view.View.draw View.java:23898 android.view.View.updateDisplayListIfDirty View.java:22767 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5138 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 androidx.drawerlayout.widget.DrawerLayout.drawChild DrawerLayout.java:1478 crc640ec207abc449b2ca.ShellFlyoutRenderer.n_drawChild(Native Method) crc640ec207abc449b2ca.ShellFlyoutRenderer.drawChild ShellFlyoutRenderer.java:57 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.draw View.java:23901 com.android.internal.policy.DecorView.draw DecorView.java:1378 android.view.View.updateDisplayListIfDirty View.java:22767 android.view.ThreadedRenderer.updateViewTreeDisplayList ThreadedRenderer.java:602 android.view.ThreadedRenderer.updateRootDisplayList ThreadedRenderer.java:608 android.view.ThreadedRenderer.draw ThreadedRenderer.java:684 android.view.ViewRootImpl.draw ViewRootImpl.java:5440 android.view.ViewRootImpl.performDraw ViewRootImpl.java:5148 android.view.ViewRootImpl.performTraversals ViewRootImpl.java:4212 android.view.ViewRootImpl.doTraversal ViewRootImpl.java:2919 android.view.ViewRootImpl$TraversalRunnable.run ViewRootImpl.java:10491 android.view.Choreographer$CallbackRecord.run Choreographer.java:1108 android.view.Choreographer.doCallbacks Choreographer.java:866 android.view.Choreographer.doFrame Choreographer.java:797 android.view.Choreographer$FrameDisplayEventReceiver.run Choreographer.java:1092 android.os.Handler.handleCallback Handler.java:938 android.os.Handler.dispatchMessage Handler.java:99 android.os.Looper.loopOnce Looper.java:226 android.os.Looper.loop Looper.java:313 android.app.ActivityThread.main ActivityThread.java:8669 java.lang.reflect.Method.invoke(Native Method) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run RuntimeInit.java:571 com.android.internal.os.ZygoteInit.main ZygoteInit.java:1135

FM1973 avatar Nov 22 '22 18:11 FM1973

another one:

Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* ) Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* ) Android.Views.View.DispatchDraw(Canvas ) Microsoft.Maui.Platform.ContentViewGroup.DispatchDraw(Canvas canvas) Android.Views.View.n_DispatchDraw_Landroid_graphics_Canvas_(IntPtr , IntPtr , IntPtr ) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_V(_JniMarshal_PPL_V , IntPtr , IntPtr , IntPtr ) java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@de9dae6 android.graphics.BaseCanvas.throwIfCannotDraw BaseCanvas.java:87 android.graphics.RecordingCanvas.throwIfCannotDraw RecordingCanvas.java:264 android.graphics.BaseRecordingCanvas.drawBitmap BaseRecordingCanvas.java:97 android.graphics.drawable.BitmapDrawable.draw BitmapDrawable.java:560 android.widget.ImageView.onDraw ImageView.java:1444 android.view.View.draw View.java:23898 android.view.View.updateDisplayListIfDirty View.java:22767 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 crc6452ffdc5b34af3a0f.ContentViewGroup.n_dispatchDraw(Native Method) crc6452ffdc5b34af3a0f.ContentViewGroup.dispatchDraw ContentViewGroup.java:59 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.draw View.java:23901 androidx.core.widget.NestedScrollView.draw NestedScrollView.java:2209 android.view.View.updateDisplayListIfDirty View.java:22767 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.updateDisplayListIfDirty View.java:22753 android.view.View.draw View.java:23628 android.view.ViewGroup.drawChild ViewGroup.java:5355 androidx.recyclerview.widget.RecyclerView.drawChild RecyclerView.java:5204 android.view.ViewGroup.dispatchDraw ViewGroup.java:5112 android.view.View.draw View.java:23901 androidx.recyclerview.widget.RecyclerView.draw RecyclerView.java:4603 android.view.View.updateDisplayListIfDirty View.java:22767 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ViewGroup.recreateChildDisplayList ViewGroup.java:5339 android.view.ViewGroup.dispatchGetDisplayList ViewGroup.java:5311 android.view.View.updateDisplayListIfDirty View.java:22714 android.view.ThreadedRenderer.updateViewTreeDisplayList ThreadedRenderer.java:602 android.view.ThreadedRenderer.updateRootDisplayList ThreadedRenderer.java:608 android.view.ThreadedRenderer.draw ThreadedRenderer.java:684 android.view.ViewRootImpl.draw ViewRootImpl.java:5445 android.view.ViewRootImpl.performDraw ViewRootImpl.java:5153 android.view.ViewRootImpl.performTraversals ViewRootImpl.java:4217 android.view.ViewRootImpl.doTraversal ViewRootImpl.java:2924 android.view.ViewRootImpl$TraversalRunnable.run ViewRootImpl.java:10513 android.view.Choreographer$CallbackRecord.run Choreographer.java:1108 android.view.Choreographer.doCallbacks Choreographer.java:866 android.view.Choreographer.doFrame Choreographer.java:797 android.view.Choreographer$FrameDisplayEventReceiver.run Choreographer.java:1092 android.os.Handler.handleCallback Handler.java:938 android.os.Handler.dispatchMessage Handler.java:99 android.os.Looper.loopOnce Looper.java:226 android.os.Looper.loop Looper.java:313 android.app.ActivityThread.main ActivityThread.java:8751 java.lang.reflect.Method.invoke(Native Method) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run RuntimeInit.java:571 com.android.internal.os.ZygoteInit.main ZygoteInit.java:1135

FM1973 avatar Nov 22 '22 18:11 FM1973

Hope this helps to nail down the problem

FM1973 avatar Nov 22 '22 18:11 FM1973

The same issue...

angelru avatar Nov 25 '22 15:11 angelru

Hope the team get the importance of this. It's a fundamental building block of all these views that images are handled correctly as a base requirement, there cannot be any room for error otherwise your app will just crash and along with it your brand image. Without this it is not possible to release any Maui app at this time unfortunately. Luckily mine was a port from Xamarin, so I've reworked the changes back into the old app that the Maui port was going to replace and will revisit in another 3 to 6 months time to see if things have improved. Incidentally the performance of the scrolling in the Maui app also would not have let us release either, but that is a different topic.

terraslate avatar Nov 26 '22 04:11 terraslate

Not only CarouselView, but the Microsoft.Maui.Controls.Image control will produce this error on switching ImageSource😓

image

1357310795 avatar Nov 26 '22 12:11 1357310795

@1357310795 Yes, I can confirm that.

FM1973 avatar Nov 26 '22 12:11 FM1973

@jsuarezruiz @mattleibow

This might need retagging. It looks as though it is unrelated to the CollectionView or CarouselView but happens in the Image control when the source is being switched.

This obviously will impact any Android Control that uses the RecyclerView under the hood (I believe this includes both CollectionView and CarouselView), since that will likely attempt to reuse the same Image Control while switching the sources as a user scrolls.

AmSmart avatar Nov 28 '22 13:11 AmSmart

I don't know if it has something to do with it, but with CollectionView with images, when you scroll quickly it seems that the source of the images is exchanged.

angelru avatar Nov 28 '22 20:11 angelru

any solution to 'Canvas: trying to use a recycled bitmap android.graphics.Bitmap@5601f7b' ?

angelru avatar Nov 30 '22 08:11 angelru

@jsuarezruiz @mattleibow @PureWeen @hartez @davidortinau @maddymontaquila

This bug has been declared multiple times and the first time in June 2022.

https://github.com/dotnet/maui/issues?q=is%3Aissue+is%3Aopen+Canvas%3A+trying+to+use+a+recycled+bitmap

When do you plan to fix it. The bug is rated high but no one is taking care of it. How do you expect us to trust Maui if the same Xamarin Forms slow fix issues happen again. As part of my company we are seriously considering moving to another technology (native or flutter). We're tired of always having to find workarounds !

mohachouch avatar Nov 30 '22 13:11 mohachouch

I spent a few hours to analyze this problem.

This bug was created following this pull request: https://github.com/dotnet/maui/pull/7348

While waiting for Microsoft to permanently fix this bug, the workaround consists of redoing the clear before each source image change.

Below is an example of code to add the clear in the source image mapping.

This workaround is applicable to the following bug https://github.com/dotnet/maui/issues/11519 https://github.com/dotnet/maui/issues/11130 https://github.com/dotnet/maui/issues/10032 https://github.com/dotnet/maui/issues/9712 https://github.com/dotnet/maui/issues/8809 https://github.com/dotnet/maui/issues/9011 https://github.com/dotnet/maui/issues/8178 https://github.com/dotnet/maui/issues/8809

using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;

namespace MauiCanvas;

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");
			});

#if __ANDROID__
        ImageHandler.Mapper.PrependToMapping(nameof(Microsoft.Maui.IImage.Source), (handler, view) => PrependToMappingImageSource(handler, view));
#endif

        return builder.Build();
	}

#if __ANDROID__
    public static void PrependToMappingImageSource(IImageHandler handler, Microsoft.Maui.IImage image)
    {
        handler.PlatformView?.Clear();
    }
#endif

}

mohachouch avatar Dec 01 '22 08:12 mohachouch

@mohachouch Man I keep my fingers crossed your workaround does it´s job. I will give it a try.... Thanks!

FM1973 avatar Dec 01 '22 09:12 FM1973

I'm struggling to understand how an issue as prominent as this one, a hard crash on android when simply displaying an image and tabbing away and back, has been seemingly ignored for so long and even moved to the backlog (on another referenced similar issue).

Thanks a lot @mohachouch for your time investigating and seemingly finding a workaround. Will definitely try this one later today.

hided avatar Dec 01 '22 09:12 hided

@mohachouch So far no crash the whole day! Thanks a lot! I can´t understand why the team was not able to provide a solution as quick as you. I know there is a lot to fix in maui, but this one made android apps unusable. Thanks again!

FM1973 avatar Dec 01 '22 17:12 FM1973

Your welcome @FM1973

I remind you that the workaround is not a correction, it's just for waiting a more permanent fix.

I noticed an strange thing, in my case I don't have to clear but just to declare the method is enough to fix the bug.

@FM1973 can you check that it works on your side ?

Not applying this workarround does not work for everyone

#if __ANDROID__
    public static void PrependToMappingImageSource(IImageHandler handler, Microsoft.Maui.IImage image)
    {
    }
#endif

@jsuarezruiz @mattleibow

According to the source code, assignment of item is done asynchronously, may be related to that :

https://github.com/dotnet/maui/blob/main/src/Core/src/Handlers/Image/ImageHandler.Android.cs#L51

mohachouch avatar Dec 02 '22 08:12 mohachouch

@mohachouch Yes, I know it´s only a workaround and it is marked as such in our source code. I will check if only declaring the method is enough, I can´t before next week, but will get back to you when done.

FM1973 avatar Dec 02 '22 08:12 FM1973

@mohachouch Not really. Still get the error without handler.PlatformView?.Clear(); With handler.PlatformView?.Clear(); all is OK.

image

image

1357310795 avatar Dec 02 '22 09:12 1357310795