【Android TimeCat】 解决 context.startforegroundservice() did not then call service.startforeground()

背景

因为这个适配没做好,被用户干了。。。

Android 8.0 有一项复杂功能;系统不允许后台应用创建后台服务。 因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。
在系统创建服务后,应用有5秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知。如果应用在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。

但是目前在调用:context.startForegroundService(intent)时报如下ANR,startForegroundService()文档说明在service启动后要调用startForeground()。

1
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()

解决

第一步:使用Context.startForegroundService()启动服务后,在serviceonCreate方法中调用startForeground()

1
2
3
4
5
6
7
8
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,CHANNEL_NAME,
NotificationManager.IMPORTANCE_HIGH);

NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);

Notification notification = new Notification.Builder(getApplicationContext(),CHANNEL_ID).build();
startForeground(1, notification);

第二步:在onStart里再次调用startForeground()

Why?

  1. Android 8.0 系统不允许后台应用创建后台服务,故只能使用Context.startForegroundService()启动服务
  2. 创建服务后,应用必须在5秒内调用该服务的 startForeground() 显示一条可见通知,声明有服务在挂着,不然系统会停止服务 + ANR 套餐送上。
  3. Notification 要加 Channel,系统的要求
  4. 为什么要在onStart里再次调用startForeground()?答:这一条主要是针对后台保活的服务,如果在服务A运行期间,保活机制又startForegroundService启动了一次服务A,那么这样不会调用服务AonCreate方法,只会调用onStart方法。如果不在onStart方法里再挂个通知的话,系统会认为你使用了 startForegroundService 却不在 5 秒内给通知,很傻地就停止服务 + ANR 套餐送上了。

参考

lyldding-HFFW 在Android O上启动Service遇到问题记录

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器