Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
142 / 148 / 116
Регистрация: 15.11.2012
Сообщений: 537
Записей в блоге: 2

Более подробный принцип работы Сервиса Android

14.11.2017, 20:58. Показов 1386. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте всем, я хочу понять, как работает Сервис Android более подробно, то о чем не показывают в видео уроках и не пишут в книгах, а если и пишут, то эту информацию не так просто найти.
В частности, объясните, кто знает такую вещь. Вот, допустим запустили мы какой-то сервис, а приложение полностью закрыли. Сервис продолжает работать. Увидеть мы это можем по существующему процессу в утилите Android Device Monitor.
Но, если наш Сервис в процессе запуска и работы обращается к какому-нибудь другому нашему пользовательскому классу в нашем приложении, то по сути, при закрытии нашего приложения, из памяти выгрузятся все наши классы и Сервис уже не сможет работать (потому что обращался к одному из классов).
Т.е., что я хочу подчеркнуть - то, что при закрытии приложения из памяти выгружаются все объекты всех классов за исключением одного объекта нашего класса Service, грубо говоря, он как статический-неубиваемый. Точнее даже приложение наше не закрывается, а остаётся работать из-за этого одного единственного объекта типа Service, а все остальные наши Объекты, Активности, выгружаются из памяти, т.е. уничтожаются.
Т.е. конкретный вопрос можно сформулировать так: при закрытии приложения, в памяти остаётся висеть только то, что было описано непосредственно в теле нашего класса Service, а всё остальное перестаёт существовать, так?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.11.2017, 20:58
Ответы с готовыми решениями:

Подробный принцип работы сканера
здравствуйте! видел, что есть подобные темы, но не то, что бы хотелось. Может кто встречал "очень" подробное описание работы...

Cобытийность. Принцип использования и принцип работы событий в jQ и GCT
Добрый день. Подготавливаюсь к собеседованию по чеклисту и не могу найти ответ на вопрос: событийность. Принцип использования и принцип...

подробный алгоритм работы программы
#include<iostream.h> /*библиотека, отвечающая за потоковый ввод-вывод*/ #include<fstream.h> /*отвечает за файловый ввод-вывод*/ int...

6
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,461
15.11.2017, 07:58
orange_rush, открою тайну - по идее существовать будет все что не собрал сборщик мусора то есть все на что есть ссылка - сохраните в поле объекта сервиса ссылку на активити и она никуда не пропадёт - то есть на экране ее конечно не будет но зомби / утечка будут доступны
1
314 / 257 / 81
Регистрация: 31.10.2016
Сообщений: 619
15.11.2017, 13:58
Цитата Сообщение от orange_rush Посмотреть сообщение
при закрытии приложения
давайте сначала определимся с этим термином.
Что в вашем понимании закрытие приложения? Выход с последней Activity? Или смахивание в списке приложений (или нажатие кнопки стоп в настройках приложения)? Или просто сворачивание приложения, и оно там висит и его система убивает при нехватке памяти?

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

И еще не забывайте (или узнайте) что есть класс Application, без которого не живет ни сервис, ни activity, в нем тоже можно что-то хранить (чтоб GC его не собрала) или инициализировать.
1
142 / 148 / 116
Регистрация: 15.11.2012
Сообщений: 537
Записей в блоге: 2
15.11.2017, 19:02  [ТС]
Цитата Сообщение от demixdn Посмотреть сообщение
давайте сначала определимся с этим термином.
Что в вашем понимании закрытие приложения? Выход с последней Activity? Или смахивание в списке приложений (или нажатие кнопки стоп в настройках приложения)? Или просто сворачивание приложения, и оно там висит и его система убивает при нехватке памяти?
Ну вообще, как раз-таки интересно понять все варианты.
Итак, вариант 1) "Выход из последней Активности" - это, как я понимаю, ты имеешь ввиду, полный выход, т.е. это равносильно тому, чтобы смахнуть приложение в списке Бэкстэка приложений. Т.е., тот самый момент когда выполняется метод onDestroy() для Активности, а не onStop(). Я имею ввиду именно это, когда говорю, что закрываю приложение.

Вариант 2) Нажатие кнопки стоп в настройках приложения. Здесь для меня не всё так легко и просто, потому что в разных версиях Андроида это выглядит по разному. На пятом Андроиде в одном из видео уроков товарищ через настройки видел все запущенные процессы на устройстве и мог их удалять. На моём 6-м андроиде такого пункта меню нет, как у него. Тем не менее, да, для каждого приложения есть кнопка "Остановить" и что это означает, я до конца не понимаю. Либо она останавливает приложение вообще полностью во всех его проявлениях, либо останавливает приложение почти полностью, но оставляет работать Сервисы Service. Или, как раз-таки, наоборот, убивает Сервис, относящийся к приложению?

Вариант 3) Мы просто свернули приложение. в данном случае я бы не рассматривал этот вариант, именно в контексте моего первоначального вопроса, чтобы в рамках данной темы хоть как-то ограничиться, дабы не развернуть здесь ВСЮ политику Андроида. Здесь как бы понятно, что Активность висит в onStop(). Тем не менее, может быть и здесь есть куда "копать", в плане возможных ситуаций, которые могут возникнуть, в том числе исключений или нехватки памяти.

Цитата Сообщение от demixdn Посмотреть сообщение
При убивании процесса, если у сервиса стоит флаг пересоздания, то система его заново пересоздаст с исходным bundle, который его стартовал. И сервис начнет свою работу сначала, либо (если вы это предусмотрели) продолжит работу с того момента как остановился.
Насчёт флага пересоздания, да, это я уже изучал, допустим он по умолчанию стоит в режиме STICKY. И здесь тоже интересно, что произойдёт, когда сервис пересоздаётся, при условии, что в коде (или в теле) нашего Сервиса были прописаны команды, которые создавали объекты других классов - пересоздаст ли все эти объекты наш Сервис или он не сможет это сделать, потому что приложение уже закрыто по Варианту (1), описанном выше.

Цитата Сообщение от demixdn Посмотреть сообщение
И еще не забывайте (или узнайте) что есть класс Application, без которого не живет ни сервис, ни activity, в нем тоже можно что-то хранить (чтоб GC его не собрала) или инициализировать.
А вот здесь, если можно, поподробнее, в каком смысле есть класс Application? В смысле, его экземпляр создаётся при запуске приложения и существует, пока существует хотя бы одна Активность или Сервис, относящиеся к это приложению или что?
0
314 / 257 / 81
Регистрация: 31.10.2016
Сообщений: 619
15.11.2017, 19:59
Лучший ответ Сообщение было отмечено orange_rush как решение

Решение

"Выход из последней Активности" != "смахнуть приложение в списке Бэкстэка приложений"
Класс Application живет себе дальше. Это легко проверить. Создаете приложение с MainActivity и Application. Вот логи кейса: зашел в MainActivity, вышел из него, снова качал по иконке приложения:
Application: onCreate() called
MainActivity: onCreate() called
MainActivity: onDestroy() called
MainActivity: onCreate() called

Как видите, нового Application: onCreate() не было, он продолжил жить и после.

И еще замечание, onDestroy() у Activity не всегда выполняется, на него полагаться не стоит.
Цитата Сообщение от orange_rush Посмотреть сообщение
"Остановить" и что это означает
вот именно такое поведение она и делает. Она убивает весь процесс, в котором запущено ваше приложения и ни для одного Activity в таком случае не вызовется onDestroy(). Можете тоже по логам проверить. Тоже самое касается и сервиса.

Цитата Сообщение от orange_rush Посмотреть сообщение
пересоздаст ли все эти объекты наш Сервис
нет, он их создаст заново (пересоздаст в моем понимании - это восстановит их в том состоянии, в котором они были до смерти). те объекты, что были там раньше умрут. И если там была закачка большого файла из инета - это тоже похерится. И начнет качать заново. Специально для закачки больших файлов нужно использовать foreground service. Почитайте, если хотите, об этом.

Я понимаю, это все несколько сложно, но так и есть. Что могу вам посоветовать, это сделать приложение с Application, Activity, Service, там по методам жизненного цикла расставить логи и начать тестировать все варианты. На своем опыте вы быстрее поймете что к чему, а не слушать абстрактные "Если нажмем эту кнопку, то все выключится."

Добавлено через 7 минут
Цитата Сообщение от orange_rush Посмотреть сообщение
класс Application
Создаете класс MyApp extends Application и в нем переопределяете метод onCreate()
В манифесте прописываете в теге application
android:name=".MyApp"
Здесь один из самых тривиальных примеров, как его можно использовать.
1
142 / 148 / 116
Регистрация: 15.11.2012
Сообщений: 537
Записей в блоге: 2
15.11.2017, 21:02  [ТС]
Цитата Сообщение от demixdn Посмотреть сообщение
нет, он их создаст заново (пересоздаст в моем понимании - это восстановит их в том состоянии, в котором они были до смерти). те объекты, что были там раньше умрут. И если там была закачка большого файла из инета - это тоже похерится. И начнет качать заново.
Я имею ввиду "пересоздаст заново" с точки зрения языка java, т.е. создаст заново объекты тех классов, которые создавал раньше. Т.е. выполнит заново весь код, который был прописан в его теле, а точнее, наверное, не во всём теле, а код из метода onCreate и при этом ему не помешает то, что закрыли последнюю Активность (или смахнули приложение из стека приложений) - он создаст объекты всех классов, которые создавал раньше. А вот если завершит работу Application, тогда уже и закроются все Сервисы. Примерно так?

Я вижу, вы мне охотно отвечаете, разрешите я немного обнаглею, и поясню, почему я изначально создал эту тему. Дело в том, что я написал вот такой код для онлайн радио (мне не сколько радио это нужно, сколько понять работу Сервиса):

В классе Сервиса я решил написать следующее (пишу основное, чтобы не загромождать кодом):
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyService extends Service {
String stream = "здесь ссылка на радио";
Boolean prepared = false;
 
public void onCreate() {
  MediaPlayer mp = new MediaPlayer;
  mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
public int onStartCommand(Intent intent, int flags, int startId) {
  if (!prepared) {
    try {
      mp.setDataSource(stream);
      mp.prepareAsync();
    } catch (IOException e) {
              e.printStackTrace();
          }
  }
  mp.start();
}
А в Активности я нажимаю кнопку, по нажатии на которую вызывается startService().
На самом деле в Сервисе я прописываю ещё одно поле boolean started, которое проверяет играет радио или на паузе и по нажатию на кнопку из Активности вновь и вновь, мы то оснавливаем, то запускаем радио. При этом, постоянно, как бы, спрашиваем "если не подготовлено prepared", то подготовить - это я сделал, подразумевая, что если, допустим, прервётся связь с интернетом, то объект MediaPlayer потеряет состояние prepared и деградирует в состояние первичной инициализации.

Так вот, я запускаю приложение, жму кнопку - радио играет. Потом смахиваю приложение из стека приложений и радио перестаёт играть. Вот тогда я и задумался о природе класса Service, почему и когда он "выключается".
0
314 / 257 / 81
Регистрация: 31.10.2016
Сообщений: 619
16.11.2017, 13:54
Любой компонент не может существовать без Application. Поэтому если пересоздается сервис, то сначала создается Application, а после создается сервис. И он начинает работать с onCreate, а после вызовется onStartCommand.
Причем я раньше ошибся, когда сказал, что в него прилетит тот же самый Intent, которым мы стартовали сервис. После пересоздания Intent равен null в параметрах метода onStartCommand, если указывать START_STICKY. Если указать START_REDELIVER_INTENT, вот тогда прилетит. Но с этим флагом нужно быть осторожней, там в его описании есть интересное поведение. И там есть заметный лаг при пересоздании, он заново запускается около минуты.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.11.2017, 13:54
Помогаю со студенческими работами здесь

Android MediaPlayer без сервиса
Добрый день. Пытаюсь разработать музыкальный плеер, прочитал кучу разной инфы в инете и появилось несколько вопросов. Насколько...

где более доступно можно почитать о импульсных БП, о принцип
где более доступно можно почитать о импульсных БП, о принципах работы, из чего состоит и тд и тп? сделал трансформаторный бп, он...

RESTful-сервиса с Spring for Android POST запрос
Здравствуйте коллеги. Отправляю GET запрос на сервер: private class DTOTask extends AsyncTask<Void, Void, DTO> { ...

Работа скрипта в Android-приложении: портирование HTML-сервиса
День добрый , приложение при старте открывает веб форму из ресурсов , а в ресурсе уже захардкодин html скрипт - который должен делать...

Ищу примеры создания сервиса для Android в RadStudio 10
Там читал что можно создавать сервис для Android. Есть примеры?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 30.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru