xamarin/Xamarin.Forms

[Bug] When running embedded the default renderers aren't using Fast Renderers

Ouverte

#8 953 ouverte le 18 déc. 2019

 (9 commentaires) (1 réaction) (0 personne assignée)C# (1 926 forks)batch import
a/embedding 📦e/3 :clock3:help wantedi/highinactivep/Androidt/bug :bug:up-for-grabs

Métriques du dépôt

Stars
 (5 644 étoiles)
Métriques de merge PR
 (Aucune PR mergée en 30 j)

Description

Description

Embedding needs to be fixed so that it uses Fast Renderers by default

Original Description

In our App we are seeing this error - not every time but often. It is a Xamarin.Android App that has a Xamarin.Forms Control embedded. If you navigate to another Xamarin.Forms Page and navigating back, this error can occur

This happens on Android only (so far i can test/reproduce it)

Error: cannot access a disposed object xamarin.forms.platform.android/Renderers/FrameRenderer.cs:115

CallStack:

Cannot access a disposed object. Object name: 'Android.Graphics.Bitmap'.

StackTrace: at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <98bbbbcbc7484ff5a4c1b5515e7634fc>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeAbstractInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <98bbbbcbc7484ff5a4c1b5515e7634fc>:0 at Android.Graphics.Bitmap.get_Height () [0x0000a] in :0 at Xamarin.Forms.Platform.Android.FrameRenderer+FrameDrawable.Draw (Android.Graphics.Canvas canvas) [0x00043] in <8e6bfbbc42c1411bbf372065ebc4eeb9>:0 at Android.Graphics.Drawables.Drawable.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x00011] in :0 at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.98(intptr,intptr,intptr)18.12.2019 09:33:28: Creating Async

https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs

Steps to Reproduce

Not so easy. i'm sorry i don't have a minimal app.

Expected Behavior

Actual Behavior

Basic Information

  • Version with issue: Xamarin Forms 4.3

  • Last known good version: Unknown; We saw this error once with 3.6 but with 4.3 very often - but not sure if it's the new Xamarin.Forms or changes in our code that changed the timing

  • IDE: VisualStudio 2019 16.3.10 / 16.4

  • Platform Target Frameworks:

    • Android: 9.0 API Level 28- Pie

Analyses

The CallStack shows the problem in FrameRenderer line 115. The Problem is: __normalBitmap is disposed at this point (again: not every time but it can happen!)

The Fix

Before Line 115 add this If-Block:

if (_normalBitmap?.Handle == IntPtr.Zero) { _normalBitmap = null; }

So if the bitmap is disposed, just let the renderer create a new one.

Maybe the underlaying problem is somewhere else to be fixed but that was the place where we were able to see and fix it.

To workaround that in your own app

Create a new Class "FrameRendererEx.cs" and copy the complete FrameRenderer into it - with the new line i described above.

to use your own renderer: Add this to your MainActivity.cs `static void RegisterRenderer(Type handler, Type target) {

        var types = typeof(Page).Assembly.GetTypes();
        var registrar = types.First((t) => t.Name == "Registrar" && t.Namespace == "Xamarin.Forms.Internals");
        var props = registrar.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
        var property = props.First((p) => p.Name == "Registered");
        object registered = property.GetValue(registrar);
        var register = registered.GetType().GetMethod("Register", 0, new Type[] { typeof(Type), typeof(Type) });
        register.Invoke(registered, new object[] { handler, target });
    }`

And call it in the OnCreate like this (after an Xamarin.Forms.Forms.Init(...)) RegisterRenderer(typeof(Frame), typeof(FrameRendererEx));

If someone knows where to find the root cause of why the bitmap is disposed, let me know.

I would suggest the line described above (check the Handle of the bitmap) as a Bugfix to make the FrameRenderer more stable.

Thank you

Guide contributeur