Жизненный цикл службы и приложения Android

Я немного смущен. Я читал, что самым большим преимуществом использования запущенной службы является то, что она не зависит от приложения, поэтому, даже если Android убивает ваше приложение, ваша служба все еще жива. Тогда мои вопросы:

1) Если мой сервис работает в том же процессе, что и приложение, то сервис тоже будет жить?

2) Я использую BroadcastReceiver для обнаружения изменений в подключении устройства, поэтому, если приложение будет убито, а служба нет, буду ли я по-прежнему получать эти изменения подключения?

3) Если я хочу получить текущий статус подключения от службы, могу ли я сделать это с помощью getApplicationContext() или он может вернуть null? Во втором случае, как мне получить текущее состояние сети?

4) Как и в случае с подключением, я отправляю событие через шину Отто каждый раз, когда приложение меняет свой статус с переднего плана на фон (при приостановлении/возобновлении приложения). Итак, мой сервис подписан на эти изменения, чтобы знать текущий статус приложения. Если мое приложение будет убито, могу ли я доверять этим событиям? Или их нельзя было отправить?


person FVod    schedule 26.02.2016    source источник


Ответы (3)


Во-первых, если вы используете передний план Service, маловероятно, что он будет внезапно уничтожен. Было сказано, что:

Если мой сервис работает в том же процессе, что и приложение, сервис тоже будет жить?

Ну нет. Ваш Service является одним из компонентов вашего приложения. Если оно живо, то и приложение живо (см. также третий вопрос). Но если вы вернете START_STICKY или START_REDELIVER_INTENT из onStartCommand(), то он будет воссоздан при прекращении системой (не при принудительной остановке) как можно скорее.

Я использую BroadcastReceiver для обнаружения изменений в подключении устройства, поэтому, если приложение будет убито, а служба нет, буду ли я по-прежнему получать эти изменения подключения?

Для статического BroadcastReceiver (зарегистрированного в Manifest): это зависит от того, как было завершено ваше приложение. Если пользователь принудительно остановил его, то приемник снова начнет работать только после того, как пользователь снова запустит ваше приложение. Во всех остальных случаях: статический приемник будет цел, а если приемник создавался и регистрировался динамически, то при выключении Activity/Service нужно вовремя отменять регистрацию, чтобы избежать утечек памяти, поэтому такие ресиверы не предназначены для все равно работают 24/7.

Если я хочу получить текущий статус подключения от службы, могу ли я сделать это с помощью getApplicationContext() или он может вернуть значение null?

Это проще: Service, как и Activity, расширяет ContextWrapper. Так что, если он запущен и работает, вы можете позвонить getApplicationContext().

Я отправляю событие через шину Отто каждый раз, когда приложение меняет свой статус с переднего плана на фон (при приостановлении/возобновлении приложения)... Если мое приложение убито, могу ли я доверять этим событиям? Или их нельзя было отправить?

Я думаю, что здесь вы можете перепутать Application и Activity. Потому что, если нужно уведомить Service, то вы, скорее всего, думаете о видимой части вашего приложения и о чем-то вроде знаменитого входящего телефонного звонка.

В этом случае ваша активность может уведомить Service либо в onPause(), либо в onStop(). Оба гарантированно вызываются с Version HONEYCOMB.

Теперь я должен признаться, что не уверен в EventBus Отто, но один из вариантов, который, безусловно, сработает, - это иметь Service с START_REDELIVER_INTENT и уведомить Службу, вызвав startService(myNotifyingIntent).

Обычно процесс вашего приложения не будет мгновенно уничтожен только потому, что текущий Activity больше не находится на переднем плане. Так что вполне вероятно, что Service получит любое уведомление, которое вы отправляете от onPause().

person Bö macht Blau    schedule 26.02.2016
comment
Большое спасибо за ваш ответ. Один вопрос: у меня есть действие, которое полностью зависит от результата службы, чтобы установить все его представления. Итак, было бы хорошей практикой просто увеличить представления в методе onCreate действия, а затем в методе onServiceConnected настроить все представления действия? Увидит ли пользователь странное поведение (или служба будет привязана так быстро, что пользователь никогда ничего не заметит? Еще раз спасибо! - person FVod; 26.02.2016
comment
@FVod - Одним из таких вариантов использования для меня было приложение аудиоплеера с виджетом на главном экране с воспроизведением / паузой и т. Д., А также информация о названии / исполнителе и такая же информация / элементы управления в MainActivity. Моя активность увеличивает представления в onCreate(), а затем в onResume() запускает службу, которая должна собирать всю информацию о текущем состоянии MediaPlayer и отправлять ее (локальную трансляцию) в активность. Только тогда он сможет обновить содержимое View. Похоже, оно хорошо работает (по сравнению с другими приложениями) на Samsung Galaxy S3mini (Jellybean), но, конечно, никто не может точно сказать, какое именно устройство существует. - person Bö macht Blau; 26.02.2016

Вы неправильно поняли Activity и Приложение в Android. Подробнее о жизненном цикле службы можно узнать здесь.

person amukhachov    schedule 26.02.2016

1) Служба умирает по умолчанию. Но вы можете переопределить onStartCommand и вернуть START_STICKY. Есть и другие флаги. Так что читайте об этом подробнее https://developer.android.com/reference/android/app/Service.html#START_STICKY

2) Да, я бы взял изменения у получателя.

3) getApplicationContext() не должен возвращать NULL.

4) Если ваше приложение было убито, onPause должен был быть вызван. Таким образом, служба знает, что приложение работает в фоновом режиме. Когда вы запускаете приложение, onResume вызывает, поэтому служба также будет знать, что приложение находится на переднем плане.

person Alexander    schedule 26.02.2016