问题描述
背景
我有一个业余时间的应用程序,我已经使用了几年了(),我会尽力处理尽可能多的崩溃(我讨厌看到崩溃报告!)。
问题
最近一次崩溃似乎很新,这个:
android.app.RemoteServiceException:
at android.app.ActivityThread $ H.handleMessage(ActivityThread。 java:1768)android.os.Handler.dispatchMessage处的
(Handler.java:106)android.os.Looper.loop处的
(Looper.java:164)android.app处的
.ActivityThread.main(ActivityThread.java:6494)
在java.lang.reflect.Method.invoke(Method.java)
在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit .java:438)com.android.internal.os.ZygoteInit.main上的
(ZygoteInit.java:807)
那是我所看到的全部...
这似乎仅发生在Android 8.1上。由于该应用程序必须非常受欢迎,因此我非常确定它仅会在Android 8.1上出现。
我尝试过的操作
在Internet上搜索,我可以找到类似的崩溃,但是在所有崩溃中,它们都有更多线索。
所以我试图回想一下我最近做了什么更改。唯一的变化是将支持库迁移到Android-X。其余的更改都很小,我认为它们可能不是它的原因。
由于我没有更多的线索了,所以我决定关于Android-X部分的报告(有关更多信息,请参见
后来我集成了Firebase Crashlytics,并获得了此功能,因为我不认为这是因为我试图解决问题,而且看起来很具体。每个此类日志上方的微小线索:
致命异常:android.app.RemoteServiceException
startForeground的错误通知:java .lang.RuntimeException:服务通知的无效通道:Notification(channel = channel_id__app_monitor pri = 0 contentView = null振动= null声音= null默认值= 0x0标志= 0x40 color = 0x00000000 category = service vis = SECRET)
这很奇怪,因为我确实正确打开了服务,否则它根本不会起作用,这尤其奇怪,它仅在Android 8.1上发生,而不是在8.0上发生,例如,它对启动前台服务的要求相同。
此有问题的通知是有关前台服务的,我用于全局监视与应用程序相关的事件(仅来自受广播接收者限制的Android O)。它在2种情况下得到了更新:
- 区域设置更改
- 在出现的某些对话框中选中一个复选框在某些时候(单击对话框时)。
当我测试了这两种软件后,它们在两个Android上都可以正常工作8.0和8.1。
以下是创建/更新通知的代码:
@JvmStatic
fun getUpdatedAppMonitorNotification(context:Context):通知{
val builder = Builder(context,context.getString(R.string.channel_id__app_monitor))。setSmallIcon(R.drawable.ic_stat_app_icon) //
.setPriority(Notification.PRIORITY_DEFAULT).setCategory(Notification.CATEGORY_SERVICE)
builder.setVisibility(NotificationCompat.VISIBILITY_SECRET)
builder.setShowWhen(false)
if(!PreferenceUtil .getBooleanPref(context,R.string.pref__avoid_showing_app_monitor_notification_dialog,false))
builder.setContentT itle(context.getString(R.string.app_monitor__notification_title))
if(VERSION.SDK_INT< VERSION_CODES.P){
val mainIntent = Intent(context,MainActivity :: class.java)
.putExtra(MainActivity.EXTRA_OPENED_FROM_NOTIFICATION,true)
builder.setContentIntent(PendingIntent.getActivity(context, 0,mainIntent,PendingIntent.FLAG_UPDATE_CURRENT))
}否则{
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE,context.packageName)
.putExtra (Settings.EXTRA_CHANNEL_ID,context.getString(R.string.channel_id__app_monitor))
valendingIntent = PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(pendingIntent)
builder b}
return builder.build()
}
和代码I在服务中使用:
重写onStartCommand(intent:Intent ?,标志:I nt,startId:Int):Int {
NotificationId.initNotificationsChannels(this)
val notification = getUpdatedAppMonitorNotification(this)
startForeground(NotificationId.APP_MONITOR,notification)
...
return super.onStartCommand(intent,flags,startId)
}
是我从其他地方调用的代码,用于更新通知:
@JvmStatic
fun updateAppMonitorNotification(context:Context ){
if(VERSION.SDK_INT< VERSION_CODES.O)
返回
val通知= AppMonitorService.getUpdatedAppMonitorNotification(上下文)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE)作为NotificationManager
notificationManager.notify(NotificationId.APP_MONITOR ,通知)
}
问题
-
为什么会发生?关于Android X吗?或通知构建有问题吗?
-
为什么仅在Android 8.1上发生?
好的,我仍然不知道为什么会这样,但是我发现的一种解决方法是,通过安全地通过 context.startForegroundService
函数调用该服务,使该服务完成其通知的所有更新。 / p>
到目前为止,通过使用它,我仍然看不到任何此类崩溃。
Background
I have a spare time app that I've been working on for some years (here), and I try to handle as many crashes as I can (I hate seeing crash reports!).
The problem
One recent crash that seem quite new, is this one:
android.app.RemoteServiceException:
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1768)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:164)
at android.app.ActivityThread.main (ActivityThread.java:6494)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
And that's all that I see...
It seems to occur only for Android 8.1. Since the app has got to be quite popular, I'm very sure it will still occur only on Android 8.1.
What I've tried
Searching the Internet, I could find similar crashes, but in all of them, they had more clues.
So I tried to recall what the recent changes that I've done. The only changes were of migrating the support library to Android-X. The rest of the changes are very minor and I don't think they can be the cause for it.
Because I don't have any further clues, I decided to report about the Android-X part here (more information there, if needed), as I don't believe it's because of me trying to fix issues, and it looks like something very specific.
Later I integrated Firebase Crashlytics, and got this tiny additional clue above each such log:
Fatal Exception: android.app.RemoteServiceException
Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=channel_id__app_monitor pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 category=service vis=SECRET)
This is weird, because I do open the service correctly, otherwise it wouldn't have worked at all, and this is especially weird that this occurs only on Android 8.1, and not on 8.0 for example, which has the same requirement of how to start a foreground service.
This problematic notification is of a foreground service that I use to globally monitor app-related events (only from Android O, which has restrictions of BroadcastReceivers). It gets updated on 2 cases:
- Locale change
- Ticking a checkbox on some dialog that appears at some point (upon clicking on the dialog).
When I've tested both of those, they work fine, on both Android 8.0 and 8.1.
Here's the code to create/update the notification:
@JvmStatic
fun getUpdatedAppMonitorNotification(context: Context): Notification {
val builder = Builder(context, context.getString(R.string.channel_id__app_monitor)).setSmallIcon(R.drawable.ic_stat_app_icon)//
.setPriority(Notification.PRIORITY_DEFAULT).setCategory(Notification.CATEGORY_SERVICE)
builder.setVisibility(NotificationCompat.VISIBILITY_SECRET)
builder.setShowWhen(false)
if (!PreferenceUtil.getBooleanPref(context, R.string.pref__avoid_showing_app_monitor_notification_dialog, false))
builder.setContentTitle(context.getString(R.string.app_monitor__notification_title))
if (VERSION.SDK_INT < VERSION_CODES.P) {
val mainIntent = Intent(context, MainActivity::class.java)
.putExtra(MainActivity.EXTRA_OPENED_FROM_NOTIFICATION, true)
builder.setContentIntent(PendingIntent.getActivity(context, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT))
} else {
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
.putExtra(Settings.EXTRA_CHANNEL_ID, context.getString(R.string.channel_id__app_monitor))
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(pendingIntent)
}
return builder.build()
}
And the code I use in the service:
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
NotificationId.initNotificationsChannels(this)
val notification = getUpdatedAppMonitorNotification(this)
startForeground(NotificationId.APP_MONITOR, notification)
...
return super.onStartCommand(intent, flags, startId)
}
And this is the code I call from other places, to update the notification:
@JvmStatic
fun updateAppMonitorNotification(context: Context) {
if (VERSION.SDK_INT < VERSION_CODES.O)
return
val notification = AppMonitorService.getUpdatedAppMonitorNotification(context)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(NotificationId.APP_MONITOR, notification)
}
The questions
Why does it occur? Is it about Android X ? Or something wrong with the notification building?
Why does it occur only on Android 8.1 ?
OK, I still don't know why this occurs, but a workaround for this that I've found, is to let the service do all of the updating of its notification, by safely just calling it via the context.startForegroundService
function.
So far, by using this instead, I still don't see any crashes of this sort.
这篇关于为什么在创建/更新通知时会收到RemoteServiceException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!