Maui icon indicating copy to clipboard operation
Maui copied to clipboard

PopupExtensions.ShowPopupAsync throwing 'Java.Lang.RuntimeException: Unable to add window -- token android.os.BinderProxy@18889ed is not valid; is your activity running?'

Open ac-lap opened this issue 2 years ago • 11 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

  • [X] I have read the "Reporting a bug" section on Contributing file: https://github.com/CommunityToolkit/Maui/blob/main/CONTRIBUTING.md#reporting-a-bug

Current Behavior

I have a .net MAUI app published to Play Store, from appcenter diagnostics I am seeing this exception resulting into crashes in production. I need help to understand why this could be happening and how to fix it.

It's coming whiel trying to show the Popup, PopupExtensions.ShowPopupAsync(). I am not able to reproduce the issue. Stack trace -

Java.Lang.RuntimeException: Unable to add window -- token android.os.BinderProxy@18889ed is not valid; is your activity running?

Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* )
Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
Android.App.Dialog.Show()
CommunityToolkit.Maui.Core.Views.MauiPopup.Show()
CommunityToolkit.Maui.Core.Handlers.PopupHandler.MapOnOpened(PopupHandler handler, IPopup view, Object result)
Microsoft.Maui.CommandMapper`2.<>c__DisplayClass6_0[[CommunityToolkit.Maui.Core.IPopup, CommunityToolkit.Maui.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[CommunityToolkit.Maui.Core.Handlers.PopupHandler, CommunityToolkit.Maui.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<Add>b__0(IElementHandler h, IElement v, Object o)
Microsoft.Maui.CommandMapper.InvokeCore(String key, IElementHandler viewHandler, IElement virtualView, Object args)
Microsoft.Maui.CommandMapper.Invoke(IElementHandler viewHandler, IElement virtualView, String property, Object args)
Microsoft.Maui.Handlers.ElementHandler.Invoke(String command, Object args)
CommunityToolkit.Maui.Views.PopupExtensions.CreatePopup(Page page, Popup popup)
CommunityToolkit.Maui.Views.PopupExtensions.CreateAndShowPopupAsync[FolderInput](Page page, FolderInput popup)
CommunityToolkit.Maui.Views.PopupExtensions.ShowPopupAsync[FolderInput](Page page, FolderInput popup)

>>MyAppXX.Views.Pages.Home.addXX_tap(Object sender, EventArgs e)
>>MyAppXX.Controls.AqButton.OnGridTapped(Object sender, TappedEventArgs e)

Microsoft.Maui.Controls.TapGestureRecognizer.SendTapped(View sender, Func`2 getPosition)
Microsoft.Maui.Controls.Platform.TapGestureHandler.OnTap(Int32 count, MotionEvent e)
Microsoft.Maui.Controls.Platform.InnerGestureListener.Android.Views.GestureDetector.IOnGestureListener.OnSingleTapUp(MotionEvent e)
Android.Views.GestureDetector.IOnGestureListenerInvoker.n_OnSingleTapUp_Landroid_view_MotionEvent_(IntPtr , IntPtr , IntPtr )
Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_Z(_JniMarshal_PPL_Z , IntPtr , IntPtr , IntPtr )

>>android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@d5ab681 is not valid; is your activity running?

android.view.ViewRootImpl.setView ViewRootImpl.java:1400
android.view.WindowManagerGlobal.addView WindowManagerGlobal.java:408
android.view.WindowManagerImpl.addView WindowManagerImpl.java:154
android.app.Dialog.show Dialog.java:361
crc64338477404e88479c.InnerGestureListener.n_onSingleTapUp(Native Method)
crc64338477404e88479c.InnerGestureListener.onSingleTapUp InnerGestureListener.java:80
android.view.GestureDetector.onTouchEvent GestureDetector.java:752
mono.android.view.View_OnTouchListenerImplementor.n_onTouch(Native Method)
mono.android.view.View_OnTouchListenerImplementor.onTouch View_OnTouchListenerImplementor.java:31
android.view.View.dispatchTouchEvent View.java:15055
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3126
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2799
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
android.view.ViewGroup.dispatchTransformedTouchEvent ViewGroup.java:3132
android.view.ViewGroup.dispatchTouchEvent ViewGroup.java:2813
com.android.internal.policy.DecorView.superDispatchTouchEvent DecorView.java:571
com.android.internal.policy.PhoneWindow.superDispatchTouchEvent PhoneWindow.java:1899
android.app.Activity.dispatchTouchEvent Activity.java:4403
androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent WindowCallbackWrapper.java:70
com.android.internal.policy.DecorView.dispatchTouchEvent DecorView.java:529
android.view.View.dispatchPointerEvent View.java:15334
android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent ViewRootImpl.java:6955
android.view.ViewRootImpl$ViewPostImeInputStage.onProcess ViewRootImpl.java:6742
android.view.ViewRootImpl$InputStage.deliver ViewRootImpl.java:6161
android.view.ViewRootImpl$InputStage.onDeliverToNext ViewRootImpl.java:6218
android.view.ViewRootImpl$InputStage.forward ViewRootImpl.java:6184
android.view.ViewRootImpl$AsyncInputStage.forward ViewRootImpl.java:6349
android.view.ViewRootImpl$InputStage.apply ViewRootImpl.java:6192
android.view.ViewRootImpl$AsyncInputStage.apply ViewRootImpl.java:6406
android.view.ViewRootImpl$InputStage.deliver ViewRootImpl.java:6165
android.view.ViewRootImpl$InputStage.onDeliverToNext ViewRootImpl.java:6218
android.view.ViewRootImpl$InputStage.forward ViewRootImpl.java:6184
android.view.ViewRootImpl$InputStage.apply ViewRootImpl.java:6192
android.view.ViewRootImpl$InputStage.deliver ViewRootImpl.java:6165
android.view.ViewRootImpl.deliverInputEvent ViewRootImpl.java:9303
android.view.ViewRootImpl.doProcessInputEvents ViewRootImpl.java:9254
android.view.ViewRootImpl.enqueueInputEvent ViewRootImpl.java:9222
android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent ViewRootImpl.java:9442
android.view.InputEventReceiver.dispatchInputEvent InputEventReceiver.java:292
android.os.MessageQueue.nativePollOnce(Native Method)
android.os.MessageQueue.next MessageQueue.java:341
android.os.Looper.loopOnce Looper.java:168
android.os.Looper.loop Looper.java:299
android.app.ActivityThread.main ActivityThread.java:8261
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run RuntimeInit.java:559
com.android.internal.os.ZygoteInit.main ZygoteInit.java:954

Expected Behavior

App should not crash.

Steps To Reproduce

Production issue, unable to reproduce.

Link to public reproduction project repository

Production issue, no repro URL

Environment

- .NET MAUI CommunityToolkit: 6.0.0
- OS: Android 9 to Android 13
- .NET MAUI: net7.0-android/8.0.100

Anything else?

No response

ac-lap avatar Jan 10 '24 16:01 ac-lap

Hi @ac-lap. We have added the "needs reproduction" label to this issue, which indicates that we cannot take further action. This issue will be closed automatically in 5 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost avatar Jan 10 '24 17:01 ghost

@bijington this issue I am seeing in production, hence don't have repro. I am looking for guidance on how to fix it.

ac-lap avatar Jan 10 '24 18:01 ac-lap

@ac-lap It would be difficult to say without being able to reproduce it or know when it happens, do you know when it happens?

I did a quick google search for the error message which came across this:

https://stackoverflow.com/questions/27087983/unable-to-add-window-token-null-is-not-valid-is-your-activity-running

I don't know whether this helps or not but might be a place to start looking

bijington avatar Jan 10 '24 18:01 bijington

I see your env is outdated, please try with the latest versions of .NET MAUI and MCT

VladislavAntonyuk avatar Jan 10 '24 20:01 VladislavAntonyuk

@ac-lap , I found a condition that causes the exception below.

Unable to add window -- token android.os.BinderProxy@ef67fa6 is not valid; is your activity running?

This exception occurs if the ShowPopupAsync method is called even though the Page from which the Popup is displayed has already been destroyed.

This is a very crude method, but I verified it below.

~Page1()
{
    IDispatcherTimer timer;
    timer = Dispatcher.CreateTimer();
    timer.Interval = new TimeSpan(0, 0, 0, 0, 30000);
    timer.Tick += (s, e) =>
    {
        timer.Stop();

        MainThread.BeginInvokeOnMainThread(() =>
        {
            try
            {
                TestPopup tp = new TestPopup();
                this.ShowPopupAsync(tp);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        });
    };
    timer.Start();
}

You can easily cause this problem by moving the app to the background immediately after the destructor is called and starting another app that consumes a lot of memory.

Since I can't reproduce the same conditions as you, I set a timer in the destructor and call the ShowPopupAsync method. Isn't there a part where the ShowPopupAsync method is called on a page that has already been destroyed?

cat0363 avatar Jan 11 '24 00:01 cat0363

@bijington , If you need a reproduction code, let me know. To reproduce this problem, you need a situation similar to what I described earlier.

As an aside, this problem occurs even in the latest version.

cat0363 avatar Jan 11 '24 01:01 cat0363

@cat0363 can you check if the DisconnectHandler method is called or if you subscribe to HandlerChanged the value will be null? For me this is more a edge case that I want to think if we can prevent it

pictos avatar Jan 11 '24 02:01 pictos

I will upload the reproduction code below first. https://github.com/cat0363/MauiComm-IssuePopupShow.git

@pictos , I'll post it here when I find out.

cat0363 avatar Jan 11 '24 05:01 cat0363

@pictos , In the case where the exception occurred, DisconnectHandler was not being called. At least the exception occurs when opening the Popup, so before calling the DisconnectHandler method.

The locations where errors occur vary depending on the timing, but we investigated the status of the Activity at the locations below where errors occur frequently.

[src\CommunityToolkit.Maui.Core\Handlers\Popup\PopUpHandler.android.cs]

public static void MapOnOpened(PopupHandler handler, IPopup view, object? result)
{
	handler.PlatformView.Show();
}

Before calling the Show method above, I inserted the code below to check the status of the Activity.

System.Diagnostics.Debug.WriteLine(handler.PlatformView.Context.GetActivity()?.IsFinishing);

The value of IsFinishing was True in cases where an exception occurred, and the value of IsFinishing was False in cases where an exception did not occur.

If I were to add a guard condition, it would look like this:

[src\CommunityToolkit.Maui.Core\Handlers\Popup\PopUpHandler.android.cs]

public static void MapOnOpened(PopupHandler handler, IPopup view, object? result)
{
	if (handler.PlatformView.Context.GetActivity() is Activity activity && !activity.IsFinishing)
	{
		handler.PlatformView.Show();
	}
}

Exceptions occur infrequently in other places as well, so they cannot be fully enumerated.

As far as I investigated, the exception also occurs when creating the MauiPopup below.

[src\CommunityToolkit.Maui.Core\Handlers\Popup\PopUpHandler.android.cs]

protected override MauiPopup CreatePlatformElement()
{
	_ = MauiContext ?? throw new InvalidOperationException("MauiContext is null, please check your MauiApplication.");
	_ = MauiContext.Context ?? throw new InvalidOperationException("Android Context is null, please check your MauiApplication.");

	return new MauiPopup(MauiContext.Context, MauiContext);
}

By the way, if an exception occurs at the above location, a Null Pointer Exception has occurred.

Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference   at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 20830
   at Java.Interop.JniPeerMembers.JniInstanceMethods.FinishCreateInstance(String constructorSignature, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods.cs:line 174
   at Android.App.Dialog..ctor(Context context) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.App.Dialog.cs:line 142
   at CommunityToolkit.Maui.Core.Views.MauiPopup..ctor(Context context, IMauiContext mauiContext) in C:\Users
tester\Documents\GitHub\Maui\src\CommunityToolkit.Maui.Core\Views\Popup\MauiPopup.android.cs:line 22
   at CommunityToolkit.Maui.Core.Handlers.PopupHandler.CreatePlatformElement() in C:\Users
tester\Documents\GitHub\Maui\src\CommunityToolkit.Maui.Core\Handlers\Popup\PopUpHandler.android.cs:line 109
   at Microsoft.Maui.Handlers.ElementHandler`2[[CommunityToolkit.Maui.Core.IPopup, CommunityToolkit.Maui.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[CommunityToolkit.Maui.Core.Views.MauiPopup, CommunityToolkit.Maui.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].OnCreatePlatformElement() in D:\a\_work\1\s\src\Core\src\Handlers\Element\ElementHandlerOfT.cs:line 46
   at Microsoft.Maui.Handlers.ElementHandler.CreatePlatformElement() in D:\a\_work\1\s\src\Core\src\Handlers\Element\ElementHandler.cs:line 101
   at Microsoft.Maui.Handlers.ElementHandler.SetVirtualView(IElement view) in D:\a\_work\1\s\src\Core\src\Handlers\Element\ElementHandler.cs:line 50
   at Microsoft.Maui.Controls.Element.SetHandler(IElementHandler newHandler) in D:\a\_work\1\s\src\Controls\src\Core\Element\Element.cs:line 921
   at Microsoft.Maui.Controls.Element.set_Handler(IElementHandler value) in D:\a\_work\1\s\src\Controls\src\Core\Element\Element.cs:line 863
   at Microsoft.Maui.Platform.ElementExtensions.ToHandler(IElement view, IMauiContext context) in D:\a\_work\1\s\src\Core\src\Platform\ElementExtensions.cs:line 96
   at CommunityToolkit.Maui.Views.PopupExtensions.CreatePopup(Page page, Popup popup) in C:\Users
tester\Documents\GitHub\Maui\src\CommunityToolkit.Maui\Views\Popup\PopupExtensions.shared.cs:line 118
   at CommunityToolkit.Maui.Views.PopupExtensions.CreateAndShowPopupAsync[TestPopup](Page page, TestPopup popup, CancellationToken token) in C:\Users
tester\Documents\GitHub\Maui\src\CommunityToolkit.Maui\Views\Popup\PopupExtensions.shared.cs:line 142
   at CommunityToolkit.Maui.Views.PopupExtensions.ShowPopupAsync[TestPopup](Page page, TestPopup popup, CancellationToken token) in C:\Users
tester\Documents\GitHub\Maui\src\CommunityToolkit.Maui\Views\Popup\PopupExtensions.shared.cs:line 85
   at MauiComm_IssuePopupShow.Page1.<Finalize>b__1_1() in C:\Users
tester\Documents\GitHub\Maui\src\MauiComm-IssuePopupShow\Page1.xaml.cs:line 27
  --- End of managed Java.Lang.NullPointerException stack trace ---
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
	at android.app.Dialog.<init>(Dialog.java:188)
	at android.app.Dialog.<init>(Dialog.java:162)
	at crc64159f3caeb1269279.MauiPopup.<init>(MauiPopup.java:41)
	at mono.java.lang.Runnable.n_run(Native Method)
	at mono.java.lang.Runnable.run(Runnable.java:31)
	at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:223)
	at android.app.ActivityThread.main(ActivityThread.java:7656)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

In the latter case I described, there seems to be no other way than to throw an exception. This is because an exception occurs in MauiPopup's constructor.

cat0363 avatar Jan 11 '24 07:01 cat0363

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 3 days. It will be closed if no further activity occurs within 2 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

ghost avatar Jan 16 '24 15:01 ghost

Amazing work @cat0363 I've removed the labels so the bot won't close it.

bijington avatar Jan 16 '24 15:01 bijington