我在Android O操作系统上使用服务类。
我计划在后台使用服务。
Android文档指出
如果你的应用程序的API级别为26或更高,系统会对使用或创建后台服务施加限制,除非应用程序本身在前台。如果应用程序需要创建前台服务,应用程序应该调用startForegroundService()。
如果使用startForegroundService(),服务抛出以下错误。
Context.startForegroundService() did not then call
Service.startForeground()
这有什么问题?
我有一个小部件,当设备处于清醒状态时,它会相对频繁地进行更新,我在短短几天内就看到了数千次崩溃。
问题触发
我甚至在我的Pixel 3 XL上也注意到了这个问题,而我本以为这款设备负载并不大。所有代码路径都被startForeground()覆盖。但后来我意识到,在很多情况下,我的服务可以很快地完成工作。我认为触发我的应用程序的原因是,在系统真正抽出时间显示通知之前,服务已经结束。
解决方案/解决方案
我摆脱了所有的崩溃。我所做的就是删除对stopSelf()的调用。(我正在考虑延迟停止,直到我非常确定通知被显示,但我不希望用户看到通知,如果它不是必要的。)当服务空闲一分钟或系统正常销毁它而不抛出任何异常时。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForeground(true);
} else {
stopSelf();
}
我也面临着同样的问题,花时间找到了一个解决方案,你可以尝试下面的代码。如果你使用服务,然后把这段代码放在onCreate,否则你使用意图服务,然后把这段代码放在onHandleIntent。
if (Build.VERSION.SDK_INT >= 26) {
String CHANNEL_ID = "my_app";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"MyApp", NotificationManager.IMPORTANCE_DEFAULT);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
}
大约有10个用户在我们的应用程序的崩溃分析中得到这个错误。
正如Kimi Chiu回答的那样:这个问题的主要原因是服务在提升到前台之前就停止了。但是断言在服务被销毁后并没有停止。你可以尝试在调用startforegroundservice后添加StopService来重现这个过程
所以我测试了这个,并得以复制。
我应用的一个解决方案是,我让服务至少停留5秒钟,这样服务就会提升到前台。现在我在测试时无法重现这个问题。
private fun stopService() {
lifecycleScope.launch {
delay(5000L)
try {
stopForeground(true)
isForeGroundService = false
stopSelf()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
让我们看看这个问题是否在我们的下一个构建中重现。
更新:)->这次没有与Context.startForegroundService()相关的问题,然后没有调用service . start前台()
之前/之后comparission - >
在- - - >
后- - - - - - >
我在@humazed答案中添加了一些代码。所以没有初始通知。这可能是个变通办法,但对我来说很管用。
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= 26) {
String CHANNEL_ID = "my_channel_01";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("")
.setColor(ContextCompat.getColor(this, R.color.transparentColor))
.setSmallIcon(ContextCompat.getColor(this, R.color.transparentColor)).build();
startForeground(1, notification);
}
}
我在小图标和通知上添加了transparentColor。
它会起作用的。