maui icon indicating copy to clipboard operation
maui copied to clipboard

Android: Tapping a notification causes second `OnCreate()` call and crash.

Open RobTF opened this issue 1 year ago • 16 comments

Description

I start with an application which generates a notification. I opted to use a foreground service to generate the notification however it doesn't seem to make a difference how the notification is generated.

The notification in the foregroun service is created like so;

                var notification = new NotificationCompat.Builder(this, "MyChannel")
                .SetContentTitle("Notification Title")
                .SetContentText("Notification Description")
                .SetSmallIcon(Resource.Drawable.DefaultNotificationIcon)
                .SetContentIntent(pendingIntent)
                .SetOngoing(true)
                .SetShowWhen(false)
                .Build();

                StartForeground(10000, notification);

I start the service in the OnCreate lifecycle callback, which results in an app with the notification present; image image

When the user taps on the notification two things happen;

1l The OnCreate lifecycle activity is called again for the same activity instance it got called for on startup. There is no call on OnDestroy.

  1. The app crashes with the following error image

Steps to Reproduce

  1. Open my reproduction project.
  2. Build and run on Android (real device or simulator)
  3. When the app launches wait for the notification to appear, and tap it.
  4. Observe crash.

Link to public reproduction project repository

https://github.com/RobTF/mauiplay/tree/master/NotificationTapIssue

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 13

Did you find any workaround?

No

Relevant log output

[AndroidRuntime] FATAL EXCEPTION: main
[AndroidRuntime] Process: com.companyname.notificationtapissue, PID: 5211
[AndroidRuntime] java.lang.IllegalStateException: View with id -1: crc640ec207abc449b2ca.ShellPageContainer#onMeasure() did not set the measured dimension by calling setMeasuredDimension()
[AndroidRuntime] 	at android.view.View.measure(View.java:26370)
[AndroidRuntime] 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6981)
[AndroidRuntime] 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
[AndroidRuntime] 	at android.view.View.measure(View.java:26357)
[AndroidRuntime] 	at androidx.recyclerview.widget.RecyclerView$LayoutManager.measureChildWithMargins(RecyclerView.java:9681)
[AndroidRuntime] 	at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1657)
[AndroidRuntime] 	at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
[AndroidRuntime] 	at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
[AndroidRuntime] 	at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
[AndroidRuntime] 	at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4012)
[AndroidRuntime] 	at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4578)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:527)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at com.google.android.material.appbar.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:149)
[AndroidRuntime] 	at com.google.android.material.appbar.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:43)
[AndroidRuntime] 	at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:2253)
[AndroidRuntime] 	at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:953)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
[AndroidRuntime] 	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891)
[AndroidRuntime] 	at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729)
[AndroidRuntime] 	at android.widget.LinearLayout.onLayout(LinearLayout.java:1638)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
[AndroidRuntime] 	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at androidx.drawerlayout.widget.DrawerLayout.onLayout(DrawerLayout.java:1263)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891)
[AndroidRuntime] 	at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1880)
[AndroidRuntime] 	at android.widget.LinearLayout.onLayout(LinearLayout.java:1640)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
[AndroidRuntime] 	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
[AndroidRuntime] 	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
[AndroidRuntime] 	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891)
[AndroidRuntime] 	at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729)
[AndroidRuntime] 	at android.widget.LinearLayout.onLayout(LinearLayout.java:1638)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
[AndroidRuntime] 	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
[AndroidRuntime] 	at com.android.internal.policy.DecorView.onLayout(DecorView.java:799)
[AndroidRuntime] 	at android.view.View.layout(View.java:23693)
[AndroidRuntime] 	at android.view.ViewGroup.layout(ViewGroup.java:6413)
[AndroidRuntime] 	at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3999)
[AndroidRuntime] 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3372)
[AndroidRuntime] 	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2328)
[AndroidRuntime] 	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9087)
[AndroidRuntime] 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231)
[AndroidRuntime] 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
[AndroidRuntime] 	at android.view.Choreographer.doCallbacks(Choreographer.java:899)
[AndroidRuntime] 	at android.view.Choreographer.doFrame(Choreographer.java:832)
[AndroidRuntime] 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
[AndroidRuntime] 	at android.os.Handler.handleCallback(Handler.java:942)
[AndroidRuntime] 	at android.os.Handler.dispatchMessage(Handler.java:99)
[AndroidRuntime] 	at android.os.Looper.loopOnce(Looper.java:201)
[AndroidRuntime] 	at android.os.Looper.loop(Looper.java:288)
[AndroidRuntime] 	at android.app.ActivityThread.main(ActivityThread.java:7872)
[AndroidRuntime] 	at java.lang.reflect.Method.invoke(Native Method)
[AndroidRuntime] 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
[AndroidRuntime] 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
**Java.Lang.IllegalStateException:** 'View with id -1: crc640ec207abc449b2ca.ShellPageContainer#onMeasure() did not set the measured dimension by calling setMeasuredDimension()'

RobTF avatar May 04 '23 14:05 RobTF

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

ghost avatar May 04 '23 18:05 ghost

I think putting [Android.App.Activity(LaunchMode = Android.Content.PM.SingleTask)] or [Android.App.Activity(LaunchMode = Android.Content.PM.SingleInstance)] on MauiAppCompatActivity would solve the problem but is that what MAUI wants to do for ALL apps?

AmrAlSayed0 avatar May 04 '23 19:05 AmrAlSayed0

[Android.App.Activity(LaunchMode = Android.Content.PM.SingleTask)]

Thanks @AmrAlSayed0 - unfortunately this still fails in exactly the same way if the user taps the notification and the activity is in the foreground already, but does fix the issue of tapping when the activity is in the background.

EDIT: To clarify, when I say "this" doesn't work, I mean either of the proposed values for LaunchMode as I tested both.

RobTF avatar May 05 '23 13:05 RobTF

Same issue here, I'm using Notifications from the Shiny.org lib

henda79 avatar May 11 '23 12:05 henda79

I am having same issue. Anyone have a workaround for this?

ne0rrmatrix avatar Jun 11 '23 23:06 ne0rrmatrix

Me too

masterofdaemon avatar Jun 12 '23 02:06 masterofdaemon

I think putting [Android.App.Activity(LaunchMode = Android.Content.PM.SingleTask)] or [Android.App.Activity(LaunchMode = Android.Content.PM.SingleInstance)] on MauiAppCompatActivity would solve the problem but is that what MAUI wants to do for ALL apps?

Changing to LaunchMode = Android.Content.PM.SingleTask) fixed it for me. But I would like to see at least a way forward that does not require this adjustment.

ne0rrmatrix avatar Jun 13 '23 05:06 ne0rrmatrix

I think putting [Android.App.Activity(LaunchMode = Android.Content.PM.SingleTask)] or [Android.App.Activity(LaunchMode = Android.Content.PM.SingleInstance)] on MauiAppCompatActivity would solve the problem but is that what MAUI wants to do for ALL apps?

Changing to LaunchMode = Android.Content.PM.SingleTask) fixed it for me. But I would like to see at least a way forward that does not require this adjustment.

This only works if killing the activity kills the app process as essentially when you tap the notification you're getting a totally fresh copy of your app. If you run foreground services etc. unfortunately, it has no effect and the crash still occurs as your app has an existing process running.

RobTF avatar Jun 20 '23 20:06 RobTF

Verified this on Visual Studio Enterprise 17.7.0 Preview 2.0. Repro on Android 13.0-API33 with below Project: NotificationTapIssue.zip

XamlTest avatar Jul 06 '23 07:07 XamlTest

Still a problem.

sfernandez131 avatar Dec 07 '23 19:12 sfernandez131

It appears to be crashing somewhere in the base.OnStart() method. I can't figure out how to debug or at least see what's going on.

sfernandez131 avatar Dec 08 '23 19:12 sfernandez131

Still a big issue. We are using .NET 8 and this is preventing us from releasing a version. Any update?

ibanezjp avatar Jan 05 '24 07:01 ibanezjp

Hi, in this video: https://youtu.be/YNkdsJTyOJE?t=64 the author has the same exception and show how to fix it.

AlleSchonWeg avatar Jan 05 '24 11:01 AlleSchonWeg

Unfortunately, the solution in the video doesn't work if you kill the activity via a "swipe up" but the app contains background processing such as a foreground service (see my note above).

The problem remains and cannot be worked around by adjusting the activity type.

RobTF avatar Jan 05 '24 13:01 RobTF

Solución: image

edwinjoelmarte avatar Jan 05 '24 20:01 edwinjoelmarte

Solución: image

@edwinjoelmarte could you please provide more detail regarding where and when in the lifecycle of the app are you doing this exactly to overcome the issue?

hugofonseca-incontrol avatar Jan 08 '24 00:01 hugofonseca-incontrol

That's assigned to the intent that's captured in the notification.

sfernandez131 avatar Jan 08 '24 05:01 sfernandez131

This is a problem for me also, using Shiny.Notifications library

konradzuse avatar Jan 31 '24 18:01 konradzuse