Xamarin.forms: [Bug] Cannot access a disposed object FastRenderers.LabelRenderer

Created on 30 Aug 2019  路  28Comments  路  Source: xamarin/Xamarin.Forms

JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer'.CrashVersion 10.1 (200363)

Stack traces
JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeNonvirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
TextView.set_TextFormatted (Java.Lang.ICharSequence value)
TextView.set_Text (System.String value)
LabelRenderer.UpdateText ()
LabelRenderer.OnElementPropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs e)
(wrapper delegate-invoke) .invoke_void_object_PropertyChangedEventArgs(object,System.ComponentModel.PropertyChangedEventArgs)
BindableObject.OnPropertyChanged (System.String propertyName)
Element.OnPropertyChanged (System.String propertyName)
BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent)
BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes)
BindingExpression.ApplyCore (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property, System.Boolean fromTarget)
BindingExpression.Apply (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property)
Binding.Apply (System.Object context, Xamarin.Forms.BindableObject bindObj, Xamarin.Forms.BindableProperty targetProperty, System.Boolean fromBindingContextChanged)
BindableObject.ApplyBindings (System.Boolean skipBindingContext, System.Boolean fromBindingContextChanged)
BindableObject.SetInheritedBindingContext (Xamarin.Forms.BindableObject bindable, System.Object value)
Element.SetChildInheritedBindingContext (Xamarin.Forms.Element child, System.Object context)
Element.b__78_0 (Xamarin.Forms.BindableObject child, System.Object bc)
BindableObjectExtensions.PropagateBindingContext[T] (Xamarin.Forms.BindableObject self, System.Collections.Generic.IList1[T] children, System.Action2[T1,T2] setChildBindingContext)
Element.OnBindingContextChanged ()
View.OnBindingContextChanged ()
Grid.OnBindingContextChanged ()
BindableObject.SetInheritedBindingContext (Xamarin.Forms.BindableObject bindable, System.Object value)
Element.SetChildInheritedBindingContext (Xamarin.Forms.Element child, System.Object context)
Element.b__78_0 (Xamarin.Forms.BindableObject child, System.Object bc)
BindableObjectExtensions.PropagateBindingContext[T] (Xamarin.Forms.BindableObject self, System.Collections.Generic.IList1[T] children, System.Action2[T1,T2] setChildBindingContext)
Element.OnBindingContextChanged ()
Cell.OnBindingContextChanged ()
BindableObject.BindingContextPropertyChanged (Xamarin.Forms.BindableObject bindable, System.Object oldvalue, System.Object newvalue)
BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent)
BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes)
BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess)
BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value)
BindableObject.set_BindingContext (System.Object value)
TemplatedItemsList`2[TView,TItem].UnhookItem (TItem item)
AsyncMethodBuilderCore+<>c.b__7_0 (System.Object state)
SyncContext+<>c__DisplayClass2_0.b__0 ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.29(intptr,intptr)

fastrenderers 5 high Android bug

Most helpful comment

@transis2

For now I'll move this one to "Ready for work" because I do believe there's an issue but I'm just not quite sure the best approach to fix at this point

Some thoughts I'd have for you in the mean time

  • If you're sticking with ListView then on the pages with ListViews that have Labels possibly null out the ItemSource in "OnDissapearing" and then reset it in "OnAppearing"
  • Try switching those ListViews to the new CollectionView. I realize it's experimental but I think this might be the better long term solution
  • Create a custom LabelRenderer to replace the default LabelRenderer
    ```C#
    public class CustomLabelRenderer : LabelRenderer
    {
    bool _isDisposed = false;
    public CustomLabelRenderer(Context context) : base(context)
    {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if(_isDisposed)
                return;

            if (this.Handle == IntPtr.Zero)
                return;

            base.OnElementPropertyChanged(sender, e);
        }

        protected override void Dispose(bool disposing)
        {
            _isDisposed = true;
            base.Dispose(disposing);
        }
    }

```

All 28 comments

@transis2 Can you please attach a small project that demonstrates this issue? Thanks!

I would like have a repro to help, but I receive this error from a user who Download App from Google Play store.
In my dev machine I never produce this error, but I will try to reproduce it.

Okay, thank you. We'll keep looking for it.

We also have this issue but unfortunately no repo to share.

@transis2 @jveltd Can you share what version of Xamarin.Forms you're using? Are you using formatted text?

@transis2 and @jveltd can you post a bit of information about the ListView you are using? Maybe the XAML for it? how often are you changing it? does it have a filter? Does the data load from the web?

This issue seems to come from a race condition with the ListView being disposed and the data source on the ListView being changed

Unhook events is being fired after the LabelRenderer attached to the ViewCell but I'm not super sure what would cause this

Unhook seems to only be called when you change the shape of the underlying collection itself and then dispose is only called when the ListView itself is removed from the view tree

so it seems like the ListView is being removed (change of page?) and then at the same time the list attached to the ListView is being modified.

I've tried to trigger the race condition myself but both of those operations seem to happen synchronously so I'm not sure how one would interrupt the other.

On iOS there's a Task.Delay that happens so I could make a guess for iOS but Android doesn't have an await

As a workaround I bet you could set the ITemSource to null on your ListView before navigating away from it or instead of using ObservableCollections just swap out the list when it changes shape opposed to relying on INCC

Though not sure if that would be too expensive for your scenario

We could add a dispose check on UpdateText inside LabelRenderer but I have a feeling that would just move the exception down the road

Or there's a leaked ViewCell somewhere that still has a bindingcontext

Hi @PureWeen,
My app is very large and I don't know what is the listview affected.

All my lists binds data locally from sqlite.
I have one that use formattedtext.

What I found after seek into app center common scenarios is that users leave and return a lot before crash.

Some example:
App.OnResume
90 min 17 sec
App.OnSleep
85 min 34 sec
App.OnResume
73 min 6 sec
App.OnSleep
73 min 5 sec
App.OnResume
73 min 3 sec
App.OnSleep
59 min 50 sec

All my listviews have compiled databinding

Here is one of my listviews

                <ListView x:Name="ResultListViewItens" HasUnevenRows="True" ItemAppearing="ResultListViewItens_ItemAppearing" VerticalOptions="FillAndExpand" ItemTapped="ResultListViewItens_ItemTapped" CachingStrategy="RecycleElement" ItemDisappearing="ResultListViewItens_ItemDisappearing" SeparatorVisibility="None">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <ViewCell.View>
                                    <Grid Padding="5" RowSpacing="3">
                                        <Image Source="{Binding Figura, Mode=OneWay}"  Margin="0,5,0,0" WidthRequest="50" HeightRequest="50" VerticalOptions="Start"/>

                                        <BoxView Color="{DynamicResource SeparatorColor}"  />
                                    </Grid>
                                </ViewCell.View>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

@transis2 so it looks like you're saying it happens during an OnResume/OnSleep ?

Is the crash always with LabelRenderer or with anything else?

@PureWeen This kind of crash is always with _LabelRenderer_

No, its not during OnResume/OnSleep because I receive other events after OnResume and before the crash.

@PureWeen I will put an event before load data into every Listview to get more info where it's happening.

@transis2

For now I'll move this one to "Ready for work" because I do believe there's an issue but I'm just not quite sure the best approach to fix at this point

Some thoughts I'd have for you in the mean time

  • If you're sticking with ListView then on the pages with ListViews that have Labels possibly null out the ItemSource in "OnDissapearing" and then reset it in "OnAppearing"
  • Try switching those ListViews to the new CollectionView. I realize it's experimental but I think this might be the better long term solution
  • Create a custom LabelRenderer to replace the default LabelRenderer
    ```C#
    public class CustomLabelRenderer : LabelRenderer
    {
    bool _isDisposed = false;
    public CustomLabelRenderer(Context context) : base(context)
    {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if(_isDisposed)
                return;

            if (this.Handle == IntPtr.Zero)
                return;

            base.OnElementPropertyChanged(sender, e);
        }

        protected override void Dispose(bool disposing)
        {
            _isDisposed = true;
            base.Dispose(disposing);
        }
    }

```

We also have this same issue. Not with FastRenders though. Just Labels. I've been trying to replicate for a while, but no luck. It does feel like a race condition though.

An update to the latest MONO seemed to clear this bug up for us. If you want the version number we're using, let me know.

@jveltd

There's been some work in that area so that wouldn't surprise me
https://github.com/mono/mono/pull/16945

Looks like it's fixed for me too. No more erros still now.

I'm going to close this one for now

Let me know if the error comes back and we can continue investigating

Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer'.
Is back on Android 10, crash reported from OnePlus6 OS 10 , Huawei p 30 PRO OS 10
XF 4.6.0.800 - Android Target build 9.0 Min build 6.0
VS 2019 Version 16.6.0

JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer'
XF 4.6.0.800 - Android Target build 10.0 Min build 5.0
VS for Mac 2019 Version 8.6.2(build 6)
Usage -
ListviewCell with two labels inside stacklayout
(using a cell selector to select cells (2 types of cells))

I'm using
Forms.SetFlags("UseLegacyRenderers");
will post here after the investigating the result.
Update-----
now crash issues are less but its is there
exception culprit is moved to Xamarin.Forms.Platform.Android.LabelRenderer from Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.LabelRenderer' 2 users 5 reports

Same issue here for Label (or Button) inside Header/Footerof CollectionView. I've tried to disable FastRenderers but without any luck, same error appeared again.

XF 4.6.0.847

StackTrace:
JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeVirtualInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
View.get_Visibility ()
VisualElementTracker.UpdateIsVisible ()
VisualElementTracker.HandlePropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs e)
(wrapper delegate-invoke) .invoke_void_object_PropertyChangedEventArgs(object,System.ComponentModel.PropertyChangedEventArgs)
BindableObject.OnPropertyChanged (System.String propertyName)
Element.OnPropertyChanged (System.String propertyName)

It's very annoying bug. I can't use Header/Footer in CollectionView, because it crashes all the time. This is stack trace for Button:

JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
View.get_Context ()
Platform.GetNativeSize (Xamarin.Forms.VisualElement view, System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.Platform.AndroidPlatform.cs:1341
Forms+AndroidPlatformServices.GetNativeSize (Xamarin.Forms.VisualElement view, System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.Platform.AndroidForms.cs:930
VisualElement.OnSizeRequest (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreVisualElement.cs:800
VisualElement.OnMeasure (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreVisualElement.cs:783
VisualElement.GetSizeRequest (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreVisualElement.cs:659
VisualElement.Measure (System.Double widthConstraint, System.Double heightConstraint, Xamarin.Forms.MeasureFlags flags) D:a1sXamarin.Forms.CoreVisualElement.cs:717
TemplatedView.OnSizeRequest (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreTemplatedView.cs:43
VisualElement.OnMeasure (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreVisualElement.cs:783
VisualElement.GetSizeRequest (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreVisualElement.cs:659
Layout.GetSizeRequest (System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreLayout.cs:132
VisualElement.Measure (System.Double widthConstraint, System.Double heightConstraint, Xamarin.Forms.MeasureFlags flags) D:a1sXamarin.Forms.CoreVisualElement.cs:717
StackLayout.CalculateNaiveLayout (Xamarin.Forms.StackLayout+LayoutInformation layout, Xamarin.Forms.StackOrientation orientation, System.Double x, System.Double y, System.Double widthConstraint, System.Double heightConstraint) D:a1sXamarin.Forms.CoreStackLayout.cs:163
StackLayout.CalculateLayout (Xamarin.Forms.StackLayout+LayoutInformation layout, System.Double x, System.Double y, System.Double widthConstraint, System.Double heightConstraint, System.Boolean processExpanders) D:a1sXamarin.Forms.CoreStackLayout.cs:123
StackLayout.LayoutChildren (System.Double x, System.Double y, System.Double width, System.Double height) D:a1sXamarin.Forms.CoreStackLayout.cs:58
Layout.UpdateChildrenLayout () D:a1sXamarin.Forms.CoreLayout.cs:266
Layout.OnSizeAllocated (System.Double width, System.Double height) D:a1sXamarin.Forms.CoreLayout.cs:224
VisualElement.SizeAllocated (System.Double width, System.Double height) D:a1sXamarin.Forms.CoreVisualElement.cs:805
Layout.ResolveLayoutChanges () D:a1sXamarin.Forms.CoreLayout.cs:392
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.26(intptr,intptr)

I'm facing same error on XF v4.7.0.968, possibly in a ItemTemplate or header/footer of a Listview, where I frequently use grids. Too much listviews around, hard to determine the source. I've tried changing orientation to reproduce error but couldn't.

JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
View.get_Context ()
Platform.GetNativeSize (Xamarin.Forms.VisualElement view, System.Double widthConstraint, System.Double heightConstraint)
Forms+AndroidPlatformServices.GetNativeSize (Xamarin.Forms.VisualElement view, System.Double widthConstraint, System.Double heightConstraint)
VisualElement.OnSizeRequest (System.Double widthConstraint, System.Double heightConstraint)
VisualElement.OnMeasure (System.Double widthConstraint, System.Double heightConstraint)
VisualElement.GetSizeRequest (System.Double widthConstraint, System.Double heightConstraint)
VisualElement.Measure (System.Double widthConstraint, System.Double heightConstraint, Xamarin.Forms.MeasureFlags flags)
Layout.LayoutChildIntoBoundingRegion (Xamarin.Forms.VisualElement child, Xamarin.Forms.Rectangle region)
Grid.LayoutChildren (System.Double x, System.Double y, System.Double width, System.Double height)
Layout.UpdateChildrenLayout ()
Layout.OnSizeAllocated (System.Double width, System.Double height)
VisualElement.SizeAllocated (System.Double width, System.Double height)
Layout.ResolveLayoutChanges ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.41(intptr,intptr)

This issue is still happening me in the latest XF 4.6.0 and 4.7.0 SRs (4.7.0.1142 and 4.6.0.1141). Most recent version I can find where problem does not occur is 4.5.0.530. I am targeting Android 10.

Still having this issue on Xamarin Forms 4.7.0 ...

Same problem for me, x.f. 4.7.0 s.r.3

@PureWeen Good Morning thought I'd tag you since this issue has been closed before it might fall through the cracks
I do have the same problem.
Version v4.7.0.1239
Version v4.7.0.1260
Both Versions are broken for me

Actually sorry there already is a new issue:
https://github.com/xamarin/Xamarin.Forms/issues/10801

Was this page helpful?
0 / 5 - 0 ratings