根据 Google Play Console 崩溃和 ANR,我的应用程序在 Android 12+ 设备上遇到了很多
ForegroundServiceStartNotAllowedException
崩溃。这是因为 Google 引入了后台应用程序无法启动前台服务的限制。
该应用程序是一个音乐播放器。
我没有 Android 12+ 设备,因此我设置了运行 Android 13 的模拟器来进行复制。但是,我无法复制此崩溃,我想知道这是否是因为我正在使用模拟器。 有没有办法设置模拟器来确保它发生?
以下是 Google Play Console 报告的堆栈跟踪示例:
Exception java.lang.RuntimeException:
at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5261)
at android.app.ActivityThread.-$$Nest$mhandleServiceArgs
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2447)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:226)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8757)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)
Caused by android.app.ForegroundServiceStartNotAllowedException:
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
at android.os.Parcel.readParcelableInternal (Parcel.java:4787)
at android.os.Parcel.readParcelable (Parcel.java:4755)
at android.os.Parcel.createExceptionOrNull (Parcel.java:3018)
at android.os.Parcel.createException (Parcel.java:3007)
at android.os.Parcel.readException (Parcel.java:2990)
at android.os.Parcel.readException (Parcel.java:2932)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground (IActivityManager.java:6978)
at android.app.Service.startForeground (Service.java:743)
at github.daneren2005.dsub.util.Notifications.startForeground (Notifications.java:462)
at github.daneren2005.dsub.util.Notifications.shutGoogleUpNotification (Notifications.java:384)
at github.daneren2005.dsub.service.DownloadService.onStartCommand (DownloadService.java:317)
at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5243)
我知道应该会发生崩溃,因为我已将日志记录添加到启动前台服务的代码中:
...
Log.d(TAG, "Notifications, current state: " + ProcessLifecycleOwner.get().getLifecycle().getCurrentState());
downloadService.startForeground(notificationId, notification);
...
此时,生命周期状态为 CREATED,我认为这意味着它位于后台。但是,崩溃似乎并未发生,并且应用程序继续运行。
ActivityManager: Service.startForeground() not allowed due to bg restriction: service ga.asti.android/github.daneren2005.dsub.service.DownloadService
。 这是同样的问题吗?为什么它不会导致崩溃?有很多关于修复这个问题的指南,但是我想知道如何首先复制它,这样我知道我的修复正在起作用。
我暂时将其作为答案,除非有人可以提供一种在模拟器中产生更直观的崩溃的方法。
我发现我的应用程序在后台运行时请求前台服务的唯一迹象是配置 ActivityManager 以警告此类情况,然后按照 grep logcat 报告它们。
启用 ActivityManager 记录受限前台启动。
adb shell device_config put activity_manager \
default_fgs_starts_restriction_notification_enabled true
单击主页键将应用程序置于后台
开始观看logcat:
adb logcat -T 1 | grep ActivityManager
导致可能运行startForeground的行为(在我的应用程序中,音乐播放器:播放音乐时,在模拟器中拨打电话,接听电话,然后挂断)。
观察 logcat 输出是否有类似以下内容:
Service.startForeground() not allowed due to bg restriction: service my.app.packagename/my.app.XyzService