Pull to refresh

Comments 12

Дважды пытался использовать code.google.com/p/chrometophone/ (использующий C2DM) и соответствующие плагины к FireFox/Chrome — сначала когда эта технология только появилась, второй раз не так давно.
Фактически, это не работало. Т.е. вероятность что отосланные данные придут на телефон в течении, скажем, минуты — где-то 50/50. Часто ничего не приходило вообще. Очень редко — приходило в течении единиц секунд.
Честно говоря, я думал что это кривая реализация chrometophone или моей прошивки телефона.
Но теперь вижу что всё, видимо, хуже. Интересно, Google не смущает такая надёжность их сервиса? :)
Прямо у Google-овцев в группах можно найти ответы вида: «а никаких гарантий о доставке и нет» и «время доставки гарантировать невозможно». В чем-то я их понимаю — у них сейчас зоопарк устройств с непонятно как измененными прошивками.
На самом деле даже в документации Apple никаких гарантий нет, зато есть упоминание, что не доставленное уведомление через некоторый период времени может быть удалено с сервера. Но чудесным образом ни одно уведомление еще не потерялось.
Не знаю, как у вас отношения с Apple, у меня с их уведомлениями тоже проблема: сегодня отлично доставляется, завтра нет. И на первый айпад почему-то у меня вообще не доходят. То ли косяки с устройством, то ли с эпплом, потому что один и тот же код работает на айфоне, но не работает на айпаде.
Вопрос: правильно я понимаю, что если использовать гугловский c2dm, то требуется не только 2.2 + установленный маркет(play), но и еще чтобы юзер зашел под своим аккаунтом туда?
Хочу поделиться кое-чем, что мне удалось вычитать-надергать-проверить при разбирательстве, почему на андроиде ICQ-клиенты, не использующие C2DM либо какой-то свой протокол (чаще всего с поллингом, причем только при включенном экране), очень активно съедают батарейку. Пришел к такому выводу:

По всей видимости, блокирующее чтение из сокета создает неявный wakelock, т.е. процессор устройства не уходит в сон, но при этом Timer'ы и Handler'ы, использующиеся в приложении, останавливаются и не срабатывают. Не факт конечно, что это происходит на всех устройствах, но попробовать использовать неблокирующее чтение, пробуждающееся периодически при помощи AlarmManagera, думаю, стоит.
У вас клиент, открывающий соединение и поддерживающий показали равные результаты, по-видимому, на разных устройствах это реализовано по-разному. Либо, возможно, где-то в вашем клиенте либо в целом в процессе тестирования закрался wakelock, хотя полагаю, что вы это проверили.

Второй момент, к C2DM и андроиду в целом не относящийся, касается жестких фильтров соединений у сотовых операторов. В ходе небольшого опыта установил, что в среднем Мегафон в моем городе разрывает TCP-сессию без уведомления обеих ее сторон (последующие попытки передать что-либо по этому соединению также не приводят ни к каким ошибкам, приходится ждать таймаута), если более полутора минут не было передачи данных в обоих направлениях, т.е. просто слать на сервер сообщения не катит, нужно получать ответ. Пинги, соответственно, тоже бесполезны, т.к. проверяется состояние каждого отдельного соединения. Есть подозрение, что это одна из причин, почему C2DM столь ненадежно работает — соединение постоянно убивается провайдером, при этом клиенты об этом не знают.

Подробной проверки на спектре устройств не проводил, так что на истину не претендую, так, информация к размышлению.
Сейчас тестирую на боевом приложении и никак не мог найти причину, почему некоторые устройства уходят в оффлайн минут на 20, хотя интернет у них есть. Думал, что всему виной какая-то ошибка на сервере. Посмотрю в вашем направлении про таймауты.
Кстати, а как вы именно проводили измерение расхода батареи в вашем тесте?
Клиент в каждом keepalive-е шлет состояние своей батареи.
		private String readBattery() {
			Intent intent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
			int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
			int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
			int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
			return "battery:" + batteryLevel + " plug:" + plugged + " status:" + status;
		}


Этот метод и его применение можно найти в архиве тестового клиента.
Ссылку продублирую.
Тут, на хабре, была статья (перевод, кажется), в которой как раз говорилось о том, что операторы в целях собственной выгоды (для оптимизации ресурсов) используют не самые выгодные для клиента настройки сети, за что клиент расплачивается временем работы аппарата от батарейки.
Приведенный в примере клиент уведомлений сходит с ума, если устройству ограничен доступ к серверу уведомлений по какой-либо причине.
Например, если запускаться в корпоративной среде с выходом через WiFi и прокси, то так как прокси сервер на запросы по TCP подключению в ответ шлет хоть что-то, хотя бы 400 Bad Request, то выход из блокирующего read-а происходит и считается, что пришло уведомление. Стоит это учитывать и в боевом приложении проверять, что именно вернул read.

PS. Я не учел…
WebSocket + небольшие модификации (keep-alive) = готовое решение проблемы.
Приятная в использовании штука.
Sign up to leave a comment.

Articles

Change theme settings