Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.61
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
#1

Использование Сервисов - Программирование Android

07.02.2013, 00:15. Просмотров 2898. Ответов 28
Метки нет (Все метки)

Итак задача:
1. Сервис работает с неким сервером в сети и постоянно запрашивает у того некоторые данные.
2. Данные есть критичные и некритичные
3. Если запущено приложение, то данные отображаются в нем (все сразу или частично, пока не существенно)
4. Если приложение свернуто или вообще убито системой или девайс спит и т.д. и тп., то если Сервис получил критичные данные, должен разбудить девайс, добавить Уведомление в состояние, поднять приложение, ну и приложение получает данные для отображения.

Собственно мысли:
1. Сервис у меня уже работает и данные с сервера тягает.
2. Сделал BroadcastReceiver, Сервис туда отправляет Intent с содержанием полученных данных
3. BroadcastReciever внутри себя определяет критичность данных и при необходимости выводит Уведомление и...

Вот тут вопрос. Как данные отобразить в приложении?

Т.е. по сути объект BroadcastReceiver является частью приложения.
1. Могу ли я быть уверен, что если приложение было в Паузе или вообще в Стопе, то после вызова BroadcastReciever оно уже снова запущено с последнего Активити?
2. BroadcastReceiver один, а Активити в приложении может быть много. Каким образом мне запоминать значения всех полученных данных, чтобы при перемещении между Активити можно было потом эти данные отобразить? Где их лучше сохранить?
3. Аналогично с Уведомлениями. Появилось Уведомление с данными, а приложение-то свернуто. Тыкаем в Уведомление, приложение разворачивается, а как передать данные в приложение как будто оно было развернуто?

Ну как-то так

Пробежала мысль не париться и сделать чтобы Сервис сохранял все что получает в БД и просто вызывает BroadcastReceiver. А приложение при активации просто читает из БД актуальные данные. Т.е. Оно читает данные при активации при получении BroadcastReceiver, при развертывании через Уведомление.

Однако такой способ меня как-то смущает, ибо связь с сервером будет с периодичностью 5-10 секунд, и получается постоянная работа с БД. Насколько это ресурсоемкая операция? Вообще нормальый ли будет такой подход.

PS: Возможно слегка сумбурно объяснил, если непонятно - спрашивайте, буду корректировать мысль.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2013, 00:15
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Использование Сервисов (Программирование Android):

Гуру, Теория сервисов - Программирование Android
Гуру, Помогите! Перечитал уроки, основы понял, но суть ускользает. ТАКИХ нюансов в уроках нет... скорее инструкции чем понимание... ...

Push уведомления без сторонних сервисов - Программирование Android
Есть форма php, на которой располагается одна кнопка, при нажатии на эту кнопку на мобильный телефон (android) должно прийти push...

Как получить приблизительное местоположение пользователя без использования сервисов Google? - Программирование Android
Добрый день, Никак не могу войти под старым ником, поэтому вновь зарегистрировался. Возник вопрос о геолокации. Суть в следующем....

Использование голосовых сервисов Google в своих целях - JavaScript
Всем привет. Два вопроса тут возникло по теме топика: 1) Как известно легко можно использовать голосовой ввод от Google в своих целях. Я...

Компонент платежных сервисов - Joomla
Прива! Ребзя, нужна ваша помошь! Время терпит, но душа не имеет покоя... Проблема вот в чем. Компонент (фри-версия прилагается) пришлось...

База данных сервисов - C++ WinAPI
Здравствуйте. Объясните пожалуйста,что такое база данных сервисов.Знаю что сервис получает к ней доступ,но что это такое и где она...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
flashok
86 / 88 / 1
Регистрация: 14.02.2009
Сообщений: 293
07.02.2013, 12:14 #2
возможно эта статья вас наталкнет на какие мысли
по работе с базой
http://www.enterra.ru/blog/android_issues_with_sqlite/

p.s. интересно что вы решите в итоге
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
07.02.2013, 13:59  [ТС] #3
flashok, спасибо, довольно таки интересная статья. И, возможно, поможет в дальнейшем.
Однако сейчас меня больше интересует, какие в принципе решения могут быть.

Абстрагируясь от архитектуры андроида - имеется два куска кода, первый отвечает за получение данных, воторой за отображение данных. Прямой связи между ними нет. Так вот как средствами Андроид АПИ передавать данные между этими кусками кода. Особенно учитывая, что один из кусков кода может "спать" или вообще отсутствовать, но при "просыпании" или запуске должен отобразить актуальные данные.

Один из вариантов сохранять полученные данные в БД. Какие еще идеи?

Может как-то сохранять актуальное состояние данных в Сервисе, а Приложение либо получает Броадкаст, либо когда "просыпается" каким либо образом запрашивает информацию у Сервиса?
YuraAAA
1571 / 1313 / 270
Регистрация: 25.10.2009
Сообщений: 3,432
Записей в блоге: 2
07.02.2013, 15:17 #4
Передачу данных между активити и сервисом можно сделать с помощью паттерна Observer-Observable.

В сервис запихните внутренний класс, который будет extends Observable. Активити будет реализовывать интерфейс Observer.
dubok79
323 / 121 / 11
Регистрация: 01.11.2012
Сообщений: 586
07.02.2013, 18:21 #5
По сервисам надо прочитать уроки с 92 по 100 вот на этом ресурсе как раз там все это разбирается. Все очень понятно написано.
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
07.02.2013, 22:19  [ТС] #6
Цитата Сообщение от dubok79 Посмотреть сообщение
Все очень понятно написано.
Спасибо. Этот ресурс я уже изучал. немного сразу не догнал некоторые моменты, сейчас вчитался подробнее

Вопрос остается открытым по поводу явного наличия Активити и Сервиса в одном процессе. Как в написано в этом же источнике - "Как вы понимаете, это сработает только, если сервис и приложение выполняются в одном процессе"

Т.е. учитывая жизненный цикл приложения могу предположить, что:
1. Приложение запускается, отображается некоторое Активити, которое запускает Сервис.
2. Сервис работает и может через БроадкастРесивер или через Биндинг отдавать данные или получать доступ к методом сервиса.
3. Устройство заснуло. Активити перешло в Паузу Или вообще в Стоп, а в последствии может даже было "убито" системой.
4. Сервис по-прежнему работает, и в случае получения Критичного сообщения создает уведомление и должен где-то сохранить данные, вероятно в каком-либо своем поле.
5. Пользователь получив уведомление будит девайс и тыкает в уведомление. Уведомление открывает соответствующее Активити и вроде как Активити должно опять иметь возможность либо через БроадкастРесивер или посредством Биндинга получить доступ к Сервису. Вот тут вопрос - это Активити будет создано в том же процессе, что и Сервис?

Если восстановленное Активити создается в том же процессе что и сервис, то самым рациональным вижу просто прибиндиться еще раз и получить критичное сообщение непосредственно с Сервиса.

Т.е. Сервис работает с сетью, получает все сообщения и хранит актуальное состояние данных, в том числе накапливает критичные сообщения и создает уведомления.

По уведомлению просто открывается Активити, которое прибиндивается к Сервису и получает полный набор данных и критичных сообщений.

Подтвердите/опровергните/уточните мое понимание процесса.

Добавлено через 9 минут
Цитата Сообщение от YuraAAA Посмотреть сообщение
с помощью паттерна Observer-Observable.
Это предполагает оперативное информирование Активити об изменении в Сервисе. Но Активити может быть в Паузе, Стопе или вообще убито системой. И после восстановления Активити уже не узнает, что в Observable происходили какие либо изменения. Да и после восстановления придется снова добавляться в Observable, который является частью Сервиса, а для этого надо сперва подключиться к Сервису

Хотя отображать Критичные сообщения в случае когда Активити активно это может помочь.
dubok79
323 / 121 / 11
Регистрация: 01.11.2012
Сообщений: 586
08.02.2013, 06:04 #7
А нельзя ли в таком случае сохранять эти уведомления в каком либо файле, а активити при следующем запуске их прочитает, ну и, например, удалит. Я бы такой подход использовал.
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
08.02.2013, 08:43  [ТС] #8
Ну в таком случае удобнее все же использовать БД. Все же структурированнее будут данные.

А что смущает в приведенном мною последнем варианте?
dubok79
323 / 121 / 11
Регистрация: 01.11.2012
Сообщений: 586
08.02.2013, 09:19 #9
Цитата Сообщение от obrazer Посмотреть сообщение
Ну в таком случае удобнее все же использовать БД. Все же структурированнее будут данные.
А что смущает в приведенном мною последнем варианте?
если вопрос был ко мне:
1. БД это такая хитроопая штука в андроиде, что надо иметь рядом с собой стакан иначе понять невозможно, так же как и русскую душу.
2. Ничего не смущает, просто написал свое видение. Стараюсь использовать то, что проще для меня...
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
11.02.2013, 14:49  [ТС] #10
Цитата Сообщение от flashok Посмотреть сообщение
p.s. интересно что вы решите в итоге
Ну значится идея такова:
1. Делаем Сервис. Внутри сервиса крутится поток, который коннектится через интернет к серверу и получает различную информацию.
2. В самом же Сервисе имеется Объект Данных, хранящий все необходимые данные, в том числе и список критичных сообщений.
3. После получения данных и обновления Объекта Данных, Сервис вызывает BroadcastReсiever. Который является частью Activity.
4. Activity в ответ выполняет Bind-инг к Сервису и через него получает доступ к методам Сервиса. Сервис отдает необходимые данные, в том числе критичные сообщения и Activity их отображает (в том числе обновляет некритичные данные, если требуется). Заодно Сервис сбрасывает критичные сообщения, дабы более они не отображались
5. Одновременно, в случае наличия критичного сообщения, BroadcastReciever создает Notification, который отображается в строке состояния.
6. Если пользователь тыкает в Уведомление, то аналогично вызывается Activity, которое в свою очередь.. см.п.4
7. Если нужно передать что-то из Activity в Сервис, то делаем это через Bind-инг, либо вызывая startService с соответствующим Intent-ом. Пока не решил как правильнее и удобнее. Вероятно через Intent, потому как это и может стать самым первым запуском Сервиса и, по-сути, быть стандартным обращением и можно не заботится о наличии Сервиса при желании ему чего-то отправить.

Т.о. решаются задачи:
Сервис крутится самостоятельно и не заботится об отображении. Он хранит данные и генерирует Intent-ы к BroadcastReciever-у. Причем Activity может и не существовать вовсе - данные будут получаться и сохраняться в Сервисе до момента их получения кем либо через Bind-инг.
А отображением занимается Activity, абсолютно не заботясь, откуда данные пришли, главное их забрать у Сервиса через Bind-инг (предполагаем, что сервис неубиваем).
Момент передачи данных - при старте/рестарте Activity (если не было запущено или было в стопе/паузе или система прибила Activity в случае нехватки ресурса или вызвалась по Уведомлению), при вызове BroadcastReciever-а (оперативное уведомление Activity).

Если мои умозаключения где-то расходятся с реальностью - комментируйте. Да и просто комментируйте
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
11.02.2013, 15:49 #11
Цитата Сообщение от obrazer Посмотреть сообщение
BroadcastReсiever. Который является частью Activity.
Цитата Сообщение от obrazer Посмотреть сообщение
Причем Activity может и не существовать вовсе
значит не будет и ресивера. или я что-то не так понял?
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
11.02.2013, 16:02  [ТС] #12
Цитата Сообщение от V0v1k Посмотреть сообщение
значит не будет и ресивера. или я что-то не так понял?
Ресивер регистрируется в ОС. А значит должен вызываться и без наличия Активити. Хотя это опять же мои догадки, явного указание на это я нигде не нашел.
Создается ли Активити вместе с ресивером или, возможно, создается новый объект ресивера по данным из регистрации - я не знаю.

Однако в данном случае даже если ресивер не сработает, то и не критично, потому как ресивер нужен что бы указывать Активити, что необходимо обновить данные. Если нет Активити, то и обновлять нечего. В этой ситуации важно не потерять критичные сообщения (а они сохраняются непосредственно в свойствах Сервиса) и выдать Уведомление пользователю (что сервис может сделать и самостоятельно), при нажатии на которое запускается (возобновляется) Активити и оно в onRestart(onResume) в любом случае делает Bind-инг и получает данные с Сервиса.

Вроде бы все сходится. Или я чего-то опять упустил?
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
11.02.2013, 16:18 #13
Цитата Сообщение от obrazer Посмотреть сообщение
Который является частью Activity.
если под этим имеется ввиду что ресивер будет создан в активити, то перед закрытием активити вы должны отрегистрировать ресивер, если память не подводит. поэтому я и написал.

ну а если сам сервис нотификейшини делать будет, то все сходится, просто вы написали что ресивер их делает.
obrazer
70 / 70 / 1
Регистрация: 04.09.2012
Сообщений: 170
11.02.2013, 16:25  [ТС] #14
Цитата Сообщение от V0v1k Посмотреть сообщение
ресивер будет создан в активити, то перед закрытием активити вы должны отрегистрировать ресивер
А что будет, если не отрегистрирую? Да и еще имеется регистрация в Манифесте - она для чего тогда? Не для вызова ли вне созданного Активити?
Цитата Сообщение от V0v1k Посмотреть сообщение
ну а если сам сервис нотификейшини делать будет, то все сходится, просто вы написали что ресивер их делает.
Действительно, так и написал - вот и нашелся косячек Да, Нотификейшн должен создавать Сервис, независимо от Активити. Активити или получать Ресивер или создаваться/перезапускаться по Нотификейшену.
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
11.02.2013, 16:31 #15
Цитата Сообщение от obrazer Посмотреть сообщение
А что будет, если не отрегистрирую? Да и еще имеется регистрация в Манифесте - она для чего тогда? Не для вызова ли вне созданного Активити?
давно ресиверы не писал, так-что могу ошибаться.
ресивер можно создать независимый и зарегистрировать в манифесте, а можно создать в самой активити и там же нужно регистрировать/отрегистрировать, если закрыть активити с неотрегистрированным ресивером, то будет екзепшен.

повторяю что могу ошибаться, давно ресиверы не делал.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.02.2013, 16:31
Привет! Вот еще темы с ответами:

Удаление Гугл - сервисов - Android
Здравствуйте. Телефон - Yotaphone 2. Версия андроида - 4.4.3 Вопрос такой, как лучше удалить сервисы, приложения, библиотеки...

Docker запуск сервисов - Linux
Всем привет, у меня есть несколько контейнеров с линухами, проблема в том что при перезапуске контейнера все сервисы лежат apache mysql...

Блокировка поисковых сервисов - JavaScript
Здравствуйте! Заранее извиняюсь если подобная тема обсуждалась (не нашел). Дело вот в чем: Есть сайт с движком друпала, на нем модуль...

Порядок загрузки драйверов и сервисов - PowerShell
Дарова! Есть ли возможность в поше узнать порядок загрузки сервисов и дров, как это реализовано в лодордере от сисинтерналс? Если да, как...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.02.2013, 16:31
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru