Context.startForegroundService() ANR без фактического вызова

После обновления моего приложения до целевого API 27 (ранее 25) я сталкиваюсь со многими ANR от пользователей, которые я не могу воспроизвести. Кажется, они связаны с ограничениями фонового выполнения Oreo с сообщением ANR.

Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{73bc351 u0 com.xxx.xxxx/.player.PlayFileService}

Однако я нигде в своем коде не вызываю Context.startForegroundService(). По каким причинам может быть сгенерирован этот ANR, не являющийся результатом прямого вызова этого метода?




Ответы (2)


В моем случае, хотя я и не вызывал Context.startForegroundService() напрямую, он вызывался, потому что мое музыкальное приложение переходило в фоновый режим, а система уничтожала службу. Затем, когда пользователь через пару минут нажимал медиа-кнопку, чтобы возобновить воспроизведение, служба перезапускалась системой с этим вызовом, поскольку приложение находилось в фоновом режиме. В конце концов я позвонил startForeground(), но это было после множества настроек. Я добавил вызов startForeground() в начале onCreate() службы с пустым уведомлением, и все мои ANR исчезли.

person Steve M    schedule 01.06.2018

На основании документации:

До Android 8.0 обычным способом создания службы переднего плана было создание фоновой службы, а затем перевод этой службы на передний план. С Android 8.0 есть сложности; система не позволяет фоновому приложению создавать фоновую службу. По этой причине в Android 8.0 представлен новый метод startForegroundService() для запуска новой службы на переднем плане.

После того, как система создала службу, у приложения есть пять секунд, чтобы вызвать метод службы startForeground(), чтобы отобразить видимое пользователю уведомление новой службы. Если приложение не вызывает startForeground() в течение установленного времени, система останавливает службу и объявляет приложение ANR.

Вы можете следовать этому SO, который описывает подход к правильному запуску служба переднего плана с каналом уведомлений.

person Sagar    schedule 30.05.2018
comment
Я делаю по старинке. Я вызываю startService() только тогда, когда приложение находится на переднем плане, и вызываю startForeground(), когда активность переходит в фоновый режим с уведомлением в канале. Я нигде не вызываю новый startForegroundService() в своем приложении. - person Steve M; 30.05.2018
comment
@SteveM Вы не можете запустить службу с помощью context.startService(), когда ваше приложение находится в фоновом режиме. Вам нужно использовать startForegroundService() - person Sagar; 30.05.2018
comment
Я не запускаюService() с приложением в фоновом режиме. Если бы я это сделал, я бы получил исключение IllegalStateException. - person Steve M; 30.05.2018
comment
@SteveM, просто для ясности: вы запускаете службу, когда приложение находится на переднем плане, а когда приложение переходит в фоновый режим, вы просто делаете его передним планом? - person Sagar; 30.05.2018
comment
Да, я вызываю startforeground в onPause - person Steve M; 30.05.2018
comment
@SteveM Задали для NotificationId ненулевое значение? - person Sagar; 30.05.2018