System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Android.Widget.PopupWindow'.

1 Answer 2499 Views
DatePicker DateTimePicker
Brad
Top achievements
Rank 1
Brad asked on 15 Oct 2021, 01:31 AM

Since adding the Telerik date picker control - we are getting an intermittent error:

 

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Android.Widget.PopupWindow'.

 

Call Stack below:

 

JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
PopupWindow.set_ContentView (Android.Views.View value)
RadPopup.ClearAndroidContext ()
RadPopup.UpdatePopupContext ()
RadPopup.OnPlacementTargetRendererChanged ()
PopupBase.PlacementTarget_PropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs e)
PopupBase+<>c.<AttachWeakEventListenerForPlacementTargetPropertyChanged>b__99_0 (Telerik.XamarinForms.Primitives.PopupBase listener, System.Object sender, System.ComponentModel.PropertyChangedEventArgs eventArgs)
WeakEventListener`3[TListener,TEventSource,TEventArgs].OnEvent (System.Object sender, TEventArgs eventArgs)
(wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs(object,System.ComponentModel.PropertyChangedEventArgs)
BindableObject.OnPropertyChanged (System.String propertyName)
Element.OnPropertyChanged (System.String propertyName)
BindableObject.ClearValue (Xamarin.Forms.BindableProperty property, System.Boolean fromStyle, System.Boolean checkAccess)
BindableObject.ClearValue (Xamarin.Forms.BindableProperty property)
Platform+<>c__DisplayClass45_0.<Cleanup>g__DoCleanup|0 ()
Platform.Cleanup (System.Collections.Generic.List`1[T] viewsToRemove, System.Collections.Generic.List`1[T] renderersToDispose)
Platform.SetPage (Xamarin.Forms.Page newRoot)
Platform.Dispose ()
FormsAppCompatActivity.OnDestroy ()
Activity.n_OnDestroy (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.8(intptr,intptr)

 

This is within the dispose method of what I assume is the telerik control. 

 

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:telerikInput="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input"
             x:Class="MobileInterface.Views.QuestionText"
             Shell.PresentationMode="ModalNotAnimated">
    <ContentPage.Content>
        <StackLayout>
            <StackLayout Grid.Row="1" Grid.Column="2" Orientation="Horizontal"
                         VerticalOptions="Start" HorizontalOptions="FillAndExpand"
                         BackgroundColor="{StaticResource Primary}" Padding="10"
                         >
                <Label Text="{Binding LocationTitle}"
                       FontSize="Small"
                       HorizontalTextAlignment="Start" Grid.Column="1"
                       HorizontalOptions="FillAndExpand"
                       TextColor="White"/>
                <Label Text="{Binding Title}"
                       FontSize="Small"
                       HorizontalTextAlignment="End" Grid.Column="2"
                       HorizontalOptions="FillAndExpand"
                       TextColor="White"
                   />
            </StackLayout>
            <Label Text="{Binding QuestionText}"
                   VerticalOptions="Center" 
                   HorizontalOptions="CenterAndExpand"
                   FontSize="Medium"                   
                   Margin="10"/>
            <Entry x:Name="dataEntry"  Text="{Binding Answer, Mode=TwoWay}" 
                   FontSize="{Binding FontSize}" 
                   VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" 
                   IsVisible="{Binding IsTextType}}"
                   Keyboard="{Binding KeyboardType}"
                   Completed="dataEntry_Completed"
                   Focused="dataEntry_Focused"
                   Margin="10"/>
            <telerikInput:RadDateTimePicker
                x:Name="datePicker"
                Date="{Binding DateAnswer}"
                DefaultHighlightedDate="{Binding DateDefaultHightlight}"
                VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"
                DisplayStringFormat="d"
                SpinnerFormat="d"
                SelectionChanged="RadDateTimePicker_SelectionChanged"
                IsVisible="{Binding IsDateType}">
                <telerikInput:RadDateTimePicker.SelectorSettings>
                    <telerikInput:PickerPopupSelectorSettings>
                        <telerikInput:PickerPopupSelectorSettings.AcceptButtonStyle>
                            <Style TargetType="Button">
                                <Setter Property="TextColor" Value="White"/>
                            </Style>
                        </telerikInput:PickerPopupSelectorSettings.AcceptButtonStyle>
                        <telerikInput:PickerPopupSelectorSettings.CancelButtonStyle>
                            <Style TargetType="Button">
                                <Setter Property="TextColor" Value="White"/>
                            </Style>
                        </telerikInput:PickerPopupSelectorSettings.CancelButtonStyle>
                    </telerikInput:PickerPopupSelectorSettings>
                </telerikInput:RadDateTimePicker.SelectorSettings>
            </telerikInput:RadDateTimePicker>            
            <Button Margin="0,10,0,0" Text="{Binding ButtonText}"
                        Clicked="Button_Clicked"                        
                        BackgroundColor="{StaticResource Primary}"
                        TextColor="White" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

 

I'm not sure if the IsVisible is what's jamming me up - it's a generic page that either is text based but if the type is a date - I swap out which one is visible.

 

Any input or thoughts are appreciated on this type of error.  It appears that it's been a common one in the Xamarin history.

 

Xamarin Forms:  5.0.0.2125

Telerik.UI.for.Xamarin.Input 2021.3.915.1

(same for the DataControls)

Didi
Telerik team
commented on 01 Nov 2021, 01:53 PM

Hi Brad,

Could you please send us a sample repro project with this issue, so we can test on our side the exact setup you have. The dev team is researching the case and we want to be sure we have the complete picture of the behavior. 

I look forward to your reply
Brad
Top achievements
Rank 1
commented on 04 Nov 2021, 08:35 PM

And yes - I can repro it - but the visibility is the main issue.

1 Answer, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 15 Oct 2021, 01:53 PM | edited on 15 Oct 2021, 01:56 PM

Hello Brad,

Your suspicion is likely correct. In Xamarin.Forms on Android, when you toggle IsVisible to false, it actually gets removed from the visual tree. This is an unfortunate side effect of the way the framework handles things and is not something we can prevent.

That being said, I have opened a Feedback Portal for the team to research ways around this [Android] Prevent Dispose Exceptions when IsVisible is False (telerik.com).

Moving Forward

This problem is why we recommend you never data bind to anything that is being dynamically being added/removed from the visual tree.

For example, this KB article explains why you can run into exceptions when using a data bound control inside the RadBusyIndicator Data bound controls inside busy indicator raise exception when busy state is changed | Telerik UI for Xamarin (although you're using a different UI control, the same concept applies. So, it's worth reading that article to understand the implications).

Options

Now, onto how you can avoid this. Yes, you want to avoid removing it from the visual tree or time the logic differently so that you wait long enough on both side of visibility change.

I have a couple suggestions you can play with:

Option 1 - replace IsVisible with another Technique (recommended)

You can avoid removing the DateTimePicker from the visual tree by using Opacity and InputTransparent

 

// Makes the UI element completely transparent.
MyPicker.Opacity = 0;

// Although the elelement is transparent, the user's mouse/touch gesture are still going to be intercepted by the invisible control. To fix this, set
MyPicker.InputTransparent = true;

That code effectively does the same thing as IsVisible=False, but still leaves the objects in the visual tree to maintain any data bindings or other required objects.

Option 2 - Use separate pages for different editors

You could go one step back in the app lifecycle and do the check for string or DateTime before navigating. for example:

private void NavigateToEditorPage(object propertyToEdit)
{
    if (propertyToEdit is DateTime)
    {
        // navigate to the page that has the DatetimePicker editor GUI
        Navigation.PushModalAsync(new DateEditorPage(propertyToEdit));
    }
    else
    {
        // navigate to the page that has the string editor GUI
        Navigation.PushModalAsync(new TextEditorPage(propertyToEdit));
    }
}

> This might be a bit heavy handed for just a couple UI control differentiation, but is a reusable option (you can reuse those pages for multiple purposes). Additionally, you can encapsulate the logic for each editing UX within the individual modals.

Wrapping Up

I hope this information helps you consider alternatives and find a solution.

Regards,
Lance | Manager Technical Support
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Brad
Top achievements
Rank 1
commented on 04 Nov 2021, 08:35 PM

You rock - I've been testing it and it looks ok.  That makes quite a bit of sense.

Ganpat
Top achievements
Rank 1
commented on 03 Jan 2022, 04:44 PM | edited

I am getting the same issue :
It is very random, sometimes it occurs sometime not.


System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Android.Widget.PopupWindow'.
  at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <00c315a988634383b446eff646084784>:0
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <00c315a988634383b446eff646084784>:0
  at Android.Widget.PopupWindow.set_ContentView (Android.Views.View value) [0x00027] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-30/mcw/Android.Widget.PopupWindow.cs:599
  at Telerik.XamarinForms.Primitives.RadPopup.ClearAndroidContext () [0x0002e] in <a8f0b2531d3a43e1af8a09974e2c1c8e>:0
  at Telerik.XamarinForms.Primitives.RadPopup.UpdatePopupContext () [0x00017] in <a8f0b2531d3a43e1af8a09974e2c1c8e>:0
  at Telerik.XamarinForms.Primitives.RadPopup.OnPlacementTargetRendererChanged () [0x00000] in <a8f0b2531d3a43e1af8a09974e2c1c8e>:0
  at Telerik.XamarinForms.Primitives.PopupBase.PlacementTarget_PropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs e) [0x00012] in <a8f0b2531d3a43e1af8a09974e2c1c8e>:0
  at Telerik.XamarinForms.Primitives.PopupBase+<>c.<AttachWeakEventListenerForPlacementTargetPropertyChanged>b__99_0 (Telerik.XamarinForms.Primitives.PopupBase listener, System.Object sender, System.ComponentModel.PropertyChangedEventArgs eventArgs) [0x00000] in <a8f0b2531d3a43e1af8a09974e2c1c8e>:0
  at Telerik.XamarinForms.Common.WeakEventListener`3[TListener,TEventSource,TEventArgs].OnEvent (System.Object sender, TEventArgs eventArgs) [0x00023] in <9e9b25dc0d3245a29ae02ea29570dc43>:0
  at at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs(object,System.ComponentModel.PropertyChangedEventArgs)
  at Xamarin.Forms.BindableObject.OnPropertyChanged (System.String propertyName) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:266
  at Xamarin.Forms.Element.OnPropertyChanged (System.String propertyName) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:362
  at Xamarin.Forms.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) [0x00114] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:510
  at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x00173] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:446
  at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess) [0x0004d] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:374
  at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:349
  at Xamarin.Forms.Platform.Android.Platform.SetRenderer (Xamarin.Forms.VisualElement bindable, Xamarin.Forms.Platform.Android.IVisualElementRenderer value) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.Android\Platform.cs:376
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing) [0x000f2] in D:\a\1\s\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:329
  at Xamarin.Forms.Platform.Android.PageRenderer.Dispose (System.Boolean disposing) [0x00024] in D:\a\1\s\Xamarin.Forms.Platform.Android\Renderers\PageRenderer.cs:51
  at Java.Lang.Object.Java.Interop.IJavaPeerable.Disposed () [0x00000] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Object.cs:178
  at Java.Interop.JniRuntime+JniValueManager.DisposePeer (Java.Interop.IJavaPeerable value) [0x00038] in <00c315a988634383b446eff646084784>:0
  at Java.Lang.Object.Dispose () [0x00000] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Object.cs:210
  at Xamarin.Forms.Platform.Android.AppCompat.FragmentContainer.OnDestroyView () [0x0003c] in D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\FragmentContainer.cs:81
  at AndroidX.Fragment.App.Fragment.n_OnDestroyView (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in D:\a\1\s\generated\androidx.fragment.fragment\obj\Release\monoandroid9.0\generated\src\AndroidX.Fragment.App.Fragment.cs:2052
  at at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.108(intptr,intptr)
Didi
Telerik team
commented on 06 Jan 2022, 06:35 AM

Hi Ganpat,

If passing testing the fix for this issue will be included in the R1 2022 release of Telerik UI for Xamarin. Bug report status is in development: https://feedback.telerik.com/xamarin/1539473-datetimepicker-android-prevent-dispose-exceptions-when-isvisible-is-false

Follow the feedback item so you will receive an email notification when there is an update. 

Tags
DatePicker DateTimePicker
Asked by
Brad
Top achievements
Rank 1
Answers by
Lance | Manager Technical Support
Telerik team
Share this question
or