Страница 1 из 1

вызов функций сервиса без задержек

Добавлено: 11 сен 2013, 03:14
Idol
Подскажите, пожалуйста, наилучший способ реализации вызова функции сервиса без задержек из разных активити.
Сервис должен использовать отдельный процесс. Идет только передача параметров в сервис, обратно ничего получать не надо.

Пока мне кажется, что наилучшим будет использовать Messenger. Запуск его в головной активити (при Создании) и уничтожение в destroy головной активити.

Не доконца понятно, как правильно вызывать функции сервиса из разных активити.
Что будет с сервисом когда головная активити будет убита (по разным причинам)?

Re: вызов функций сервиса без задержек

Добавлено: 11 сен 2013, 05:49
Mikhail_dev
Как вариант, используйте сервис и AIDL для коммуникации между процессами.
1. Если держать с сервисом соединение, то задержек не будет
2. Соединение лучше держать всегда
Не доконца понятно, как правильно вызывать функции сервиса из разных активити.
Что будет с сервисом когда головная активити будет убита (по разным причинам)?
Сервис стартует как отдельный процесс и живет как отдельный процесс. Activity же если и умрет, то сервис останется жив, при этом (вроде как) будет держать биндинг с активностью, поэтому стоит в onResume и onPause подключаться и отключаться к сервису, дабы не держать нити с сервисом.
Функции сервиса вызываются также, как и функции любого другого класса. Правда есть один нюанс. Даже два.
1. bindService - асинхронный метод, который происходит обычно около 50 мс, т.е. при выполнении метода сервиса сразу же за этим методом, получите null.
2. Используя AIDL, передача данных производится объектами, реализующими интерфейс Parcelable, либо простые типы данных.

Re: вызов функций сервиса без задержек

Добавлено: 11 сен 2013, 07:16
Idol
no--,
спасибо за быстрый ответ.

Что-то я совсем потерялся в потоке информации :).
Если я правильно понимаю, AIDL самый тяжеловесный вариант, да и не особо рекомендуемый судя по документации. К тому же Messenger использует теже механизмы, что и AIDL, только с потоками нет заморочек. Мне не совсем понятна причина почему AIDL.

Что значит держать соединение, если я запускаю сервис с главного активити, могу ли я пользоваться уже этим открытым соединением (все же в одном процессе) из другого активити или все же надо отрывать новое соединение?

Вы пишите, что если соединение открыто, то задержек не будет, т.е. при открытии активити по любому будет задержка в 50мс?

Если активити по каким-то причинам была убита ОС, то сервис повис в памяти навечно?

Re: вызов функций сервиса без задержек

Добавлено: 11 сен 2013, 07:30
Idol
я пока, как говориться, нарабатываю фундамент и мне все подходы интересны. Однако, для моей конкретной задачи все решения выглядят как-то неклюже и тяжело.
Может я просто соврешаю архитектурную ошибку и все можно решить на порядок проще и элегантнее?

Конкретная задача:
Нужно проигрывать короткие звуки по вызову из разных активити. Допустимая задержка начала проигрывания <10-20мс.
Загрузка звуков (использую Sounds) просходит в головной активити, где звуки map-ся с ID из базы данных.
Соответственно, вызов звука идет по ID.

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

Может есть какой-то другой (лучший) подход, кроме сервиса?

Re: вызов функций сервиса без задержек

Добавлено: 11 сен 2013, 10:51
Mikhail_dev
Пожалуй я вряд ли смогу ответить на Ваши вопросы, но всё же сделаю некоторые предположения =)
Если я правильно понимаю, AIDL самый тяжеловесный вариант, да и не особо рекомендуемый судя по документации. К тому же Messenger использует теже механизмы, что и AIDL, только с потоками нет заморочек. Мне не совсем понятна причина почему AIDL.
Честно говоря сейчас так с ходу и не отвечу. Когда я начинал сам анализировать, что лучше использовать, у нас сервис изначально был заложен как тяжеловесный вариант, поэтому я на легковестность решения мало смотрел.
Что значит держать соединение, если я запускаю сервис с главного активити, могу ли я пользоваться уже этим открытым соединением (все же в одном процессе) из другого активити или все же надо отрывать новое соединение?
Открывать новое
Вы пишите, что если соединение открыто, то задержек не будет, т.е. при открытии активити по любому будет задержка в 50мс?
Да, но если вы её в onResume засунете, то с точки зрения юзера, он не успеет что-то запустить в 1/20 секунды, а вот с точки зрения самого кода, можно получить null, как я писал выше.
Если активити по каким-то причинам была убита ОС, то сервис повис в памяти навечно?
Да, сервис будет висеть. Он тем и хорош, что он БУДЕТ висеть и БУДЕТ выполнять необходимое задание. Активность после падения перезапустил и заново подключился к этому сервису. Правда я так понимаю, такой вариант вам не нужен.
Все это работает, когда в одном процессе. Но идет серьезная задержка UI потока при загрузке и при проигрывании относительно длинных звуков.
Я так понимаю это происходит даже при проигрывании в отдельном потоке (т.е. я надеюсь что вы не в главном потоке проигрываете), то ... то могу сказать только предположения на эту тему.
1. Возможно у вас часто срабатывает GC, следовательно следует меньше порождать объекты (к примеру в играх вообще стараются не создавать новые объекты).
2. Сервис в отдельном процессе всё же вам даёт X2 оперативной памяти для вашей программы, т.к. создается новая копия Далвик машины. Чем больше памяти, тем проще работает GC.К примеру есть замечательная статья
Почему веб-приложения на мобильных платформах работают медленно
Сделаю небольшую вырезку из статьи
СБОРЩИК МУСОРА НА МОБИЛЬНОЙ ПЛАТФОРМЕ ЭТО НЕ ТОЖЕ САМОЕ, ЧТО СБОРЩИК МУСОРА НА ДЕСКТОПЕ
Изображение
Если у вас из этой статьи в голове останется что-то одно, пусть это будет этот слайд. Ось Y — это время, потраченное на сборку мусора. Ось X — это «относительный расход памяти». Относительный к чему? К минимальному требуемому размеру памяти.
Вот то, что этот слайд нам хочет сказать: «Пока у тебя в 6 раз больше памяти, чем нужно на самом деле, ты — в шоколаде. Но горе тебе, если опустишься ниже 4 размеров требуемой памяти». Необязательно верить мне на слово:
Точнее, когда у сборщика мусора есть в 5 раз больше памяти, чем требуется, его производительность совпадает или слегка превосходит прямое управление памятью. Однако, производительность сборщика мусора быстро деградирует, когда ему требуется работать с небольшими хипами. С 3-мя размерами требуемой памяти он, в среднем, работает на 17% медленнее, а с двумя размерами — на 70% медленнее. Также сборщик мусора более подвержен пейджингу, если память дефрагментирована. В подобных условиях, все протестированные нами сборщики мусора работают на порядок медленнее прямого управления памятью.
По поводу конкретной задачи
Конкретная задача:
Нужно проигрывать короткие звуки по вызову из разных активити. Допустимая задержка начала проигрывания <10-20мс.
Загрузка звуков (использую Sounds) просходит в головной активити, где звуки map-ся с ID из базы данных.
Соответственно, вызов звука идет по ID.
Попробуйте поискать на stackoverflow, наверняка таких тем должны быть тучи
К пример, может эта поможет The correct way to play short sounds Android?

Ну и напоследок, вы когда разберетесь, может даже что-то напишете, можете сделать заметку на сайте по поводу возможных вариантов и что когда лучше использовать. Самому тема интересна, думаю сам скоро буду с точно таким же разбираться, правда у меня реализация специфического диктофона будет.

Re: вызов функций сервиса без задержек

Добавлено: 11 сен 2013, 18:10
klblk
Пример реализации Messenger (есть небольшие неровности):
http://habrahabr.ru/post/157063/
Хотя не уверен что это будет эффективно для данной задачи.
Но мой опыт взаимодействия с сервисом в другом процессе связан именно с ним)
ну и да, на null проверки не забывать делать перед отправкой сообщений сервису.

Re: вызов функций сервиса без задержек

Добавлено: 12 сен 2013, 07:43
Idol
всем спасибо за советы. Буду пробовать.