узнать больше о
аюсь создать приложение, которое позволяет пользователям регистрировать маршруты (местоположения / GPS). Чтобы убедиться, что местоположения регистрируются, даже когда экран выключен, я создалforeground service
для регистрации местоположения. Я храню места вRoom Database
который вводится в мой сервис с помощьюDagger2
.
Однако этот сервис убит Android, что, конечно, нехорошо. Я мог бы подписаться на предупреждения о нехватке памяти, но это не решает основную проблему, из-за которой мой сервис погибает через ~ 30 минут на современном высококачественном телефоне с Android 8.0
Я создал минимальный проект только с действием «Hello world» и сервисом:https://github.com/RandomStuffAndCode/AndroidForegroundService
Сервис запущен у меняApplication
класс, и ведение журнала маршрута запускается черезBinder
:
// Application
@Override
public void onCreate() {
super.onCreate();
mComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
Intent startBackgroundIntent = new Intent();
startBackgroundIntent.setClass(this, LocationService.class);
startService(startBackgroundIntent);
}
// Binding activity
bindService(new Intent(this, LocationService.class), mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT);
// mConnection starts the route logging through `Binder` once connected. The binder calls startForeground()
Мне наверное не нужноBIND_AUTO_CREATE
флаг, я тестировал различные флаги, пытаясь не убить мой сервис - пока что не повезло.
При использовании профилировщика не возникает утечек памяти, использование памяти стабильно на уровне ~ 35 Мб:
С помощьюadb shell dumpsys activity processes > tmp.txt
я могу подтвердить, чтоforegroundServices=true
и мой сервис занял 8 место в списке LRU:
Proc # 3: prcp F/S/FGS trm: 0 31592:com.example.foregroundserviceexample/u0a93 (fg-service)
Кажется, что невозможно создать приоритетный сервис, которому можно доверять, чтобы не быть убитым. Так что мы можем сделать? Что ж...
Поместите службу в отдельный процесс, пытаясь позволить Android убить пользовательский интерфейс / действия, оставив службу в покое. Возможно, поможет, но не кажется гарантиейупорствоватьвсе в сервисе например Комната базы данных. Каждая переменная, каждый пользовательский класс, каждый раз, когда любое из изменений, а затем запустить службу сSTART_STICKY
, Это кажется расточительным и не приводит к очень красивому коду, но это, вероятно, сработает ... несколько. В зависимости от того, сколько времени потребуется Android для повторного создания службы после ее уничтожения, большая часть местоположений может быть потеряна.Это действительно текущее состояние дел в фоновом режиме на Android? Нет ли лучшего способа?
РЕДАКТИРОВАТЬ: внесение в белый список приложения для оптимизации батареи (отключение его) не останавливает мой сервис от уничтожения
РЕДАКТИРОВАТЬ: ИспользованиеContext.startForegroundService()
запуск услуги не улучшает ситуацию
РЕДАКТИРОВАТЬ: Так что это действительно происходит только нанесколько устройства, но это происходит последовательно на них. Я думаю, вам придется сделать выбор: либо не поддерживать огромное количество пользователей, либо написать действительно некрасивый код. Потрясающие.