Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] Android: Crash when user turns on the dark theme (ObjectDisposedException) #11704

Closed
holecekp opened this issue Aug 8, 2020 · 29 comments
Closed
Labels
4.8.0 regression on 4.8.0 a/darkmode i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often i/regression p/Android t/bug 🐛

Comments

@holecekp
Copy link

holecekp commented Aug 8, 2020

Description

I have upgraded Xamarin.Forms to 4.8 and I am experiencing occasional crashes when I switch from light theme to the dark one in the Android settings.

I am including the output from Logcat:

FATAL EXCEPTION: main
Process: holecek.pavel.MorseCode, PID: 15147
android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.FastRenderers.ButtonRenderer'.
  at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <7b4d352c3d814e0d89e267740a59522f>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <7b4d352c3d814e0d89e267740a59522f>:0 
  at Android.Widget.TextView.set_CompoundDrawablePadding (System.Int32 value) [0x00022] in <90f729b6aa54404bb4a394bf7834877e>:0 
  at Xamarin.Forms.Platform.Android.ButtonLayoutManager.UpdateImage () [0x000a6] in <4df20df9ee5a43729dd8ba50f24273d3>:0 
  at Xamarin.Forms.Platform.Android.ButtonLayoutManager.OnElementPropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs e) [0x00065] in <4df20df9ee5a43729dd8ba50f24273d3>:0 
  at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs(object,System.ComponentModel.PropertyChangedEventArgs)
  at Xamarin.Forms.BindableObject.OnPropertyChanged (System.String propertyName) [0x00012] in <b0456989b729404aa72e9e1250aef074>:0 
  at Xamarin.Forms.Element.OnPropertyChanged (System.String propertyName) [0x00000] in <b0456989b729404aa72e9e1250aef074>:0 
  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) [0x0011b] in <b0456989b729404aa72e9e1250aef074>:0 
  at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x00173] in <b0456989b729404aa72e9e1250aef074>:0 
  at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes) [0x00000] in <b0456989b729404aa72e9e1250aef074>:0 
  at Xamarin.Forms.AppThemeBinding.ApplyCore () [0x00028] in <b0456989b729404aa72e9e1250aef074>:0 
  at Xamarin.Forms.AppThemeBinding.<.ctor>b__2_1 () [0x00000] in <b0456989b729404aa72e9e1250aef074>:0 
  at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <90f729b6aa54404bb4a394bf7834877e>:0 
  at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <90f729b6aa54404bb4a394bf7834877e>:0 
  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.46(intptr,intptr)
	at mono.java.lang.RunnableImplementor.n_run(Native Method)
	at mono.java.lang.RunnableImplementor.run(Unknown Source:0)
	at android.os.Handler.handleCallback(Handler.java:883)
	at android.os.Handler.dispatchMessage(Handler.java:100)
	at android.os.Looper.loop(Looper.java:214)
	at android.app.ActivityThread.main(ActivityThread.java:7397)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

The buttons have colors set using Styles and AppThemeBinding as follows:

            <Style TargetType="Button" ApplyToDerivedTypes="True">
                <Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource ButtonBackgroundColorLight}, Dark={StaticResource ButtonBackgroundColorDark}}" />
                <Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource TextColorLight}, Dark={StaticResource TextColorDark}}" />

                <!--
                This should fix inconsistent button shadows in Xamarin.Forms but it does not seem to help much.
                https://docs.microsoft.com/cs-cz/xamarin/xamarin-forms/platform/android/button-padding-shadow
                -->
                <Setter Property="android:Button.UseDefaultShadow" Value="True" />
                <Setter Property="android:Button.UseDefaultPadding" Value="True" />
            </Style>

Steps to Reproduce

The crash occurs randomly. Sometimes it crashes, sometimes it does not. I have experienced 2 crashes on my device when I did the following:

  1. I have a page that contains an Entry, Buttons and some other basic controls.
  2. I have opened the Android settings and turned on the dark theme.
  3. When I returned to my application, it crashed immediately.

Update: I have created a repro project and described the steps to reproduce this bug. It is below in the discussion to this issue.

Expected Behavior

The app shoud not crash when the user changes the theme.

Actual Behavior

The app sometimes crashes when the user turns on the dark theme.

Basic Information

  • Version with issue: 4.8.0.1269

  • Last known good version: Probably 4.7.0.1239 which I used in the last version of my app. Since the crash occurs only sometimes, it is hard to tell which is tha last good version.

  • IDE: Visual Studio 2019

  • Platform Target Frameworks

    • Android: v10.0
  • Nuget Packages:
    Xamarin.Forms (4.8.0.1269)
    Xamarin.Essentials (1.5.3.2)
    Xamarin.Android.Support.Design (28.0.0.3)
    Xamarin.Android.Support.v7.AppCompat (28.0.0.3)
    Xamarin.Android.Support.v4 (28.0.0.3)
    Xamarin.Android.Support.v7.CardView (28.0.0.3)
    Xamarin.Android.Support.v7.MediaRouter (28.0.0.3)
    Xamarin.AndroidX.AppCompat.Resources (1.1.0.1)
    Xamarin.AndroidX.MediaRouter (1.1.0.1)

  • Affected Devices: Tested on Xiaomi Mi A2 Lite (Android 10)

Workaround

Avoid using CollectionView. For example Stacklayout with BindableLayout.ItemsSource does not crash and it can be used in very simple cases. However, if you need any feature from CollectionView, then there is no workaround.

@holecekp holecekp added s/unverified New report that has yet to be verified t/bug 🐛 labels Aug 8, 2020
@PureWeen PureWeen added 4.8.0 regression on 4.8.0 i/regression labels Aug 8, 2020
@PureWeen
Copy link
Contributor

PureWeen commented Aug 8, 2020

@holecekp can you attach a repro please?

@StephaneDelcroix FYI possible 4.8 regression

@PureWeen PureWeen added s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. labels Aug 8, 2020
@holecekp
Copy link
Author

holecekp commented Aug 8, 2020

I will try to prepare a repro but it will be hard. I still do not know which steps are necessary for the crash to happen in my full project. The crash happens randomly. Sometimes it crashes twice in a minute; sometimes I repeat the same steps for 10 minutes without crash. I verified that the crash appears also in the debug version in the emulator.

@holecekp
Copy link
Author

holecekp commented Aug 9, 2020

One more note that might be important for finding the cause of this bug. I looked at the stack trace and the crash is in the UpdateImage method of ButtonLayoutManager
(https://github.com/xamarin/Xamarin.Forms/blob/main/Xamarin.Forms.Platform.Android/ButtonLayoutManager.cs). Some buttons in my app have icon and each icon has its version for the light and the dark theme. They are placed in the drawable and drawable-night folders.

The important thing is that I have am using AppThemeBinding to set the ImageSource property as follows:

var imageSourceLight = new FileImageSource { File = androidImageFileName };
var imageSourceDark = new FileImageSource { File = androidImageFileName };
button.SetOnAppTheme(Button.ImageSourceProperty, imageSourceLight, imageSourceDark);

It might look weird to set the same file name using AppThemeBinding, but it is necessary. If AppThemeBinding is not used, Android chooses the correct version of the image from drawable, or drawable-night folders but it does not update it immediately (the user has to select another page in Shell and return back). With AppThemeBinding, the icon is updated immediately after the theme is changed.

@holecekp
Copy link
Author

holecekp commented Aug 9, 2020

It seems that the crash is caused by a button in a DataTemplate that is used for a CollectionView. When I load different data into the CollectionView for 5 times and then turn on the dark mode, the app always crashes.

@holecekp
Copy link
Author

holecekp commented Aug 9, 2020

I have created a repro project:
ObjectDisposedRepro.zip

Steps for reproducing the crash:

  1. Launch the attached repro project
  2. Tap on the "Load data into the collection view" at least 10 times. The higher number, the bigger chance that the app crashes. Ten taps crashes the app almost certainly.
  3. Minimize the app, change the theme in the Android settings and resume the app. It crashes.

This bug is not only in XF 4.8. This steps lead to crash in all versions that contain AppThemeBinding (including 4.6.0.967)!

@samhouts samhouts added i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often a/darkmode p/Android and removed s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. labels Aug 12, 2020
@jsuarezruiz jsuarezruiz removed the s/unverified New report that has yet to be verified label Aug 25, 2020
@StephaneDelcroix StephaneDelcroix removed their assignment Oct 14, 2020
@StephaneDelcroix
Copy link
Member

@StephaneDelcroix FYI possible 4.8 regression

unlikely to be related to theme. if this error happens, it could be triggered from user code too, I guess

@dan-matthews
Copy link

I just had this in a Xamarin Shell app. I have a page with an Entry on which uses AppThemeBinding. If I navigate to that page, then to another, then switch to Dark Mode I get the following error:

JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) TextView.SetTextColor (Android.Content.Res.ColorStateList colors) TextColorSwitcher.UpdateTextColor (Android.Widget.TextView control, Xamarin.Forms.Color color, System.Action1[T] setColor)
EntryRenderer.UpdateTextColor (Xamarin.Forms.Color color)
EntryRenderer.UpdateColor ()
EntryRendererBase1[TControl].OnElementPropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs e) (wrapper delegate-invoke) <Module>.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) BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes) AppThemeBinding.ApplyCore ()

It seems that Xamarin Shell is disposing the Entry but the page is still in memory and the AppThemeBinding is still firing - which as the Entry is disposed is throwing an error.

@xamiell
Copy link

xamiell commented Dec 9, 2020

Hi, having the same issue on Android.

Xamarin.Forms 4.8.0.1560

@AswinPG
Copy link

AswinPG commented Dec 28, 2020

I am also having the same issue but it's so random I can't catch it

@stesvis
Copy link

stesvis commented Mar 22, 2021

I have the same issue in Xamarin Forms 5, not just when switching to dark mode but also back to light mode.
Maybe it has to do with using AppThemeBinding directly in styles in App.xaml?

@mrengineer7777
Copy link

I am getting this crash as well.
XF 5.0.0.2012
AppShell
CollectionView

It happens when switching the app theme, but randomly. Dozens of crashes so far.

Trace from Microsoft AppCenter crash reporting:
JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
View.SetBackgroundColor (Android.Graphics.Color color)
VisualElementRenderer1[TElement].UpdateBackgroundColor () VisualElementRenderer1[TElement].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)
BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes)
AppThemeBinding.ApplyCore ()
<.ctor>b__2_1 ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.87(intptr,intptr)

@mrengineer7777
Copy link

I think I found a workaround. I have a background service that refreshes the CollectionView list (of numbers) every few seconds. I pause the background update for 2 seconds, Task.Delay(100) to allow any update to finish, then set the AppTheme. No crashes so far.

@holecekp
Copy link
Author

@mrengineer7777 Unfortunately, this is not a workaround for all cases. In my case, nothing is refreshed periodically. All updates of the UI are done as a result of a user action (clicking a button, etc.). So there is nothing that I could pause. Also, the repro project that I have posted before is not doing any background updates at the time when the theme is changed and the app crashes.

@mrengineer7777
Copy link

@mrengineer7777 Unfortunately, this is not a workaround for all cases. In my case, nothing is refreshed periodically. All updates of the UI are done as a result of a user action (clicking a button, etc.). So there is nothing that I could pause. Also, the repro project that I have posted before is not doing any background updates at the time when the theme is changed and the app crashes.

We may be dealing with slightly different issues. Your repro states that it crashes after changing the system to dark mode. Unfortunately my test devices are Android 7 and 8 (no system option for dark). The crash on mine was happening when the user manually changed the theme in the app.

@mrengineer7777
Copy link

mrengineer7777 commented Mar 31, 2021

@holecekp I loaded your repro and tested on emulator Pixel 3 XL Q Android 10. I was eventually able to get it to crash after switching the OS from dark to light mode (I tried multiple times). Crash:
System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.FastRenderers.ButtonRenderer'.'

Something to investigate: I turned off the option "Use the concurrent garbage collector" on your repro and now I can't get it to crash. Edit: spoke too soon. I eventually got it to crash.

@mrengineer7777
Copy link

@holecekp I don't know if this is an option for you, but I just updated your repro to the latest Nugets. XF 5.0.0.2012 and Essentials 1.6.1. I also changed the target framework to Android 11 and the Target Android version to 11. I couldn't get any crashes on the Pixel 3. Lots to play with there. Sorry I can't give you any more time. Must get back to my project.

@mrengineer7777
Copy link

So much for no crashes. Sigh. My app crashes 90% of the time now when switching the app theme on Android. I'll work on a repro tomorrow (hopefully an update of @holecekp's project). This is definitely related to the Android renderer trying to reference items that have been GC'd. Point of interest: calling GC.Collect() before setting the app theme causes a crash 100% of the time on my project.

System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.Platform+DefaultRenderer'.'

@mrengineer7777
Copy link

mrengineer7777 commented Apr 1, 2021

@holecekp @PureWeen @samhouts Updated project with latest and greatest Nugets. 100% crash repro attached. Run on emulator "Pixel 3 XL Q 10.0 - API 29".

Click on [Load Data] 3 times. Click [Dark]. Click on [Load Data] 3 times. Click [Light]. You will get an app crash on either the Dark or Light click.

In this case the error is:
System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.FastRenderers.ButtonRenderer'.'

The exact element faulted varies by project.

ObjectDisposedRepro2.zip

@mrengineer7777
Copy link

More info: on my project crash on AppTheme change happens consistently on Android 8.1, but not on Android 7.1.1. Also it only happens if the user interacts with (eg taps) the CollectionView first.

@Aston13
Copy link

Aston13 commented May 14, 2021

Also reporting this issue. My AppThemeBindings are in the App.xaml.

In my app I have a CollectionView, on selecting an item the app will navigate to an item details page.

My repro steps:

  1. Select Item in CollectionView (Navigates to new page)
  2. Navigate back to CollectionView
  3. Select any Item in CollectionView (Navigates to new page)
  4. Change theme

Crash:

System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.Platform+DefaultRenderer'.'

Emulator: Pixel 2 Q 10.0 - API 29
Xamarin Forms 5.0.0.2012

@sanjeetakc
Copy link

Hi, having the same issue on Android but worked in ios

@Alex-Dobrynin
Copy link

Any solution? @PureWeen

@AlleSchonWeg
Copy link
Contributor

Hi,
i think the problem is that the native android views are already disposed, if you change the theme. I'm able to reproduce the issue in my app and before i set the theme i force a garbage collection:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Application.Current.UserAppTheme = OSAppTheme.Light;

So all the previously visited and closed views/pages are collected and when AppThemeBinding kicks in there are no theme updates on disposed views and no crash.

I have no idea how to fix this. Perhaps @jfversluis has an idea.

@jfversluis
Copy link
Member

jfversluis commented Nov 17, 2021

The initial stack traces mentions the button, we implemented a fix for that I think, can someone confirm this is still happening in the latest Forms version (SR7 5.0.0.2244)?

@AlleSchonWeg
Copy link
Contributor

This can happen everywhere, when AppThemeBinding fires the OnPropertyChanged Event. Mostly it changes a color. For example BackgroundColor.
If the color was changed then the OnElementPropertyChanged on he elements (button, entry, frame etc.) are invoked. And this method tries to change a property on the native android view. The reference to this native view still exist, but the java GC has collected the view. And than it crashes.
The main problem is, that AppThemeBinding still fireing ThemeChanged Events on XF-Controls which are already dead but not garbage collected.

@AlleSchonWeg
Copy link
Contributor

Something has changed. Perhaps an Xamrin.Android SDK Update. I'm unable to reproduce the exception anymore.

@jfversluis
Copy link
Member

Sounds good! Anyone finding this, please make sure to update to all the latest bits. If you can still reproduce with that, let me know!

@VictorKochetkov
Copy link

VictorKochetkov commented Mar 5, 2022

Same issue with Xamarin.Forms 5.0.0.2337 on Android 12

@holecekp
Copy link
Author

This crash is still in the latest Xamarin.Forms (5.0.0 SR 14)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
4.8.0 regression on 4.8.0 a/darkmode i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often i/regression p/Android t/bug 🐛
Projects
None yet
Development

No branches or pull requests