我在Android O操作系统上使用服务类。
我计划在后台使用服务。
Android文档指出
如果你的应用程序的API级别为26或更高,系统会对使用或创建后台服务施加限制,除非应用程序本身在前台。如果应用程序需要创建前台服务,应用程序应该调用startForegroundService()。
如果使用startForegroundService(),服务抛出以下错误。
Context.startForegroundService() did not then call
Service.startForeground()
这有什么问题?
为什么这个问题会发生,因为Android框架不能保证你的服务在5秒内启动,但另一方面,框架确实有严格的限制前台通知必须在5秒内触发,而不检查框架是否试图启动服务。
这绝对是一个框架问题,但并不是所有面临这个问题的开发人员都尽力了:
一个通知必须同时在onCreate和onStartCommand中,因为如果你的服务已经被创建并且你的activity试图再次启动它,onCreate将不会被调用。
通知ID不能为0,否则即使原因不同,也会发生相同的崩溃。
在start前台之前不能调用stopSelf。
有了以上3个,这个问题可以减少一点,但仍然不是一个解决方案,真正的解决方案或让我们说的变通办法是把你的目标sdk版本降低到25。
请注意,Android P很可能仍然会有这个问题,因为谷歌甚至拒绝理解发生了什么,不相信这是他们的错,阅读#36和#56以获得更多信息
我在@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。
它会起作用的。
大约有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 - >
在- - - >
后- - - - - - >
https://developer.android.com/reference/android/content/Context.html startForegroundService (android.content.Intent)
类似于startService(Intent),但是有一个隐含的承诺
Service将调用start前台(int, android.app.Notification)一次
它开始运行。该服务被赋予了相当的时间
到ANR区间做这个,否则系统会
自动停止服务并声明应用程序ANR。
与普通的startService(Intent)不同,这个方法可以在
任何时候,不管托管服务的应用程序是否在
前景的国家。
一定要打电话给服务处。在onCreate()上的start前台(int, android.app.Notification),所以你确保它将被调用..如果你有任何条件,可能会阻止你这样做,那么你最好使用正常的Context.startService(意图)并调用服务。start前台(int, android.app.Notification)你自己。
似乎Context.startForegroundService()添加了一个看门狗来确保你调用了服务。start前台(int, android.app.Notification)在它被销毁之前…