Skip to content

ViewExtensions.OnUnloaded causes app crash if the view is already disposed, this happens for web view in Blazor Hybrid apps #28051

@alexyakunin

Description

@alexyakunin

Description

We frequently see production app crashes associated the following stack trace in our Blazor Hybrid app for Android:

Exception android.runtime.JavaProxyThrowable: [System.ObjectDisposedException]: ObjectDisposed_Generic
ObjectDisposed_ObjectName_Name, Microsoft.AspNetCore.Components.WebView.Maui.BlazorAndroidWebView
  at Java.Interop.JniPeerMembers.AssertSelf (Unknown Source)
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (Unknown Source)
  at Android.Views.View.RemoveOnAttachStateChangeListener (Unknown Source)
  at Android.Views.View+<>c__DisplayClass3033_0.<remove_ViewDetachedFromWindow>b__0 (Unknown Source)
  at Java.Interop.EventHelper.RemoveEventHandler (Unknown Source)
  at Android.Views.View.remove_ViewDetachedFromWindow (Unknown Source)
  at Microsoft.Maui.Platform.ViewExtensions+<>c__DisplayClass43_0.<OnUnloaded>b__1 (Unknown Source)
  at Microsoft.Maui.Platform.ActionDisposable.Dispose (Unknown Source)
  at Microsoft.Maui.Platform.ViewExtensions+<>c__DisplayClass43_0.<OnUnloaded>b__3 (Unknown Source)
  at Java.Lang.Thread+RunnableImplementor.Run (Unknown Source)
  at Java.Lang.IRunnableInvoker.n_Run (Unknown Source)
  at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V + 0x5 (Unknown Source)
  at mono.java.lang.RunnableImplementor.n_run (RunnableImplementor.java)
  at mono.java.lang.RunnableImplementor.run (RunnableImplementor.java:29)
  at android.os.Handler.handleCallback (Handler.java:1000)
  at android.os.Handler.dispatchMessage (Handler.java:104)
  at android.os.Looper.loopOnce (Looper.java:242)
  at android.os.Looper.loop (Looper.java:362)
  at android.app.ActivityThread.main (ActivityThread.java:8393)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:552)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:992)

As you may notice, there are no own methods in this stack trace.

As far as I can judge, it's an attempt to remove native event handler on already disposed native web view triggered by the following code in ViewExtensions.OnUnloaded(...):

EventHandler<AView.ViewDetachedFromWindowEventArgs>? routedEventHandler = null;
ActionDisposable? disposable = new ActionDisposable(() =>
{
	if (routedEventHandler != null)
		view.ViewDetachedFromWindow -= routedEventHandler; // HERE
});
routedEventHandler = (_, __) => ...;

There is a number of ways to address it, but even suppression of an exception for view.ViewDetachedFromWindow -= ... would be fine for the logic in OnUnloaded.

We couldn't find a workaround for this specific issue: no own methods on call stack in this case + it seems pretty hard to replace internal BlazorAndroidWebView with our own implementation. So I'd appreciate any suggestions for Blazor Hybrid apps here in the meantime, i.e. until the moment this issue is fixed.

Steps to Reproduce

Sorry, no exact steps - the issue is happening fairly rarely in production, but frequently enough to be our #1 app crash cause.

Link to public reproduction project repository

No response

Version with bug

9.0.40 SR4

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

No response

Affected platforms

Android

Affected platform versions

No response

Did you find any workaround?

No.

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions