Pull to refresh

Comments 16

Не все Broadcast Intents равны. Некоторые из них требуют специальных разрешений (permission) для регистрации. Некоторые из них «sticky». Это означает, что как только вы регистрируете BroadcastReceiver в программе, вы сразу же получите последний Intent. Если вы зарегистрируетесь в манифесте, вы ничего не получите при регистрации. И, наконец, для некоторых Intents (SCREEN_STATE, BATTERY), вы можете зарегистрировать BroadcastReceiver только программно (регистрация в манифесте не будет иметь никакого результата).
Верно, но вот только использованные мною интенты не являются sticky, это раз. Плюс, абсолютно идентичные broadcast'ы с абсолютно идентичными intent'ами, зарегестрированные из разных мест, ведут себя по разному. Ну, а BATTERY он sticky да… а NEW_OUTGOING_CALL не sticky… a вот… впрочем не важно)
А где прочитать можно про то, какие интенты можно в манифесте прописывать, а какие бесполезно? Я час назад сел за зверский рекфакторинг и перенос ресивера батареи в манифест, ваш комментарий меня срезал.
Привет! Да, именно там, в Javadoc. Их не так уж и много. Сделано это потому, что эти события происходят часто и, потенциально, многие приложения могут на них подписываться. Было бы очень накладно инстанцировать их все каждый раз, когда меняется состояние экрана.
регистрация в oncreate, а дерегистрация в onpause — это 5.

try to turn it off and on ©
Ok, в первоначальном варианте я вообще собирался опустить unregister т.к. в нашем конетксте это не существенно. Но если Вы настаиваете, то можно обсудить. Если следовать документации: If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(), то, по хорошему, если не менять onPause, то регистрировать надо было в onResume. А может в onCreate и unregister по какому-то условию, в зависимости от логики приложения, где-то в onDestroy. Вы знаете логику данного приложения? Я лично нет, потому что это просто пример) В чем собственно вопрос?
это был не вопрос, а констатация факта.

т.к. в текущем виде, независимо от логики приложения можно создать ситуацию, в которой приложение работает, а ресивер отвалился.

навскидку, в 3.х это можно сделать через вызов системного меню.
Именно! Можно создать такую ситуацию. А теперь убедите меня, что так не было задуманно) Что если я объявлю, что ресивер должен отработать ровно до первого вызова onPause, каждый раз, когда вызывается onCreate? Не зная, что делает приложение, бессмысленно гадать, что бы оно могло сделать гипотетически. Да и речь совсем не об этом. Перенеc в onResume, чтобы не задевать ничьих эстетических предпочтений)
Мне кажется это не баг. Когда Вы регистрируете BroadcastReceiver программно, то он будет жить, пока живет Activity. То есть подразумевается, что Вы будете в жизненном цикле активити как-то обрабатывать данные, полученные через ресивер. Поэтому было бы логично получить последний интент при регистрации ресивера, чтобы, например, обновить какой-нибудь UI компонент, а не отображать его пустым. Или я не прав?
Нет. Чтобы обновить какой-нибудь UI при входе в приложение Вам достаточно проверить текущее состояние нужной Вам опции. Проверить если есть интернет, например. Для этого receiver не нужен и ждать от него ничего не нужно. Состояние системы с Вашим приходом не изменилось, значит и оповещать она никого не должна, это Вы должны узнать у нее все, что Вас интересует. А STATE_CHANGED как бы явно намекает, что произошло изменение. Вот только никакого изменения в момент запуска не было, а Вам говорят, что было. Это неправильно.
Да. Соглашусь. Я как-то не подумал об этом.
Ну, не всегда и не совсем так. Есть состояния, которые не получится проверить иначе, чем через receiver. Кроме того, писать отдельный код с проверкой текущего состояния и для обработки его изменения не слишком экономно — чаще всего действия потребуются одинаковые. То есть, логика в sticky событиях есть и весьма продуманная.

Проблема в другом: документация на все это очень кривая и часто не упоминает подобных тонкостей. Если бы там было обозначено, что использованные вами события являются sticky, думаю, вы бы не стали так возмущаться. Я сам сталкивался с тем, например, что какие-то события невозможно зарегистрировать через манифест, хотя документация про это тоже молчит. Способ борьбы один: тестировать каждую строчку кода.
Я не возмущаюсь… протестировал, рассказал. Скромные размышления. К примеру, сойдемся на том, что Wi-Fi и Data на поверку оказались sticky, хотя документация об этом молчит. В таком случае, что такого особенного в Bluetooth, что он ведет себя как обычный интент?) Если кому-то привиделось в заголовке «Ыыы, все сюда, нашел багу в Андроиде, программисты в гугле чепушилы кукурузные!», то спешу разочаровать, здесь еды нет.
Вот с этим соглашусь: такое ощущение, что разные части андроида писались людьми, никак не скоординированными. Поэтому очень похожие места ведут себя по-разному (Wifi против Bluetooth). Это я тоже замечал, когда боролся с гарнитурой — там примерно такая же разница вылезла между проводной и синезубой. Ну а документацию, разумеется, писала отдельная команда, которая часто забывала описать «несущественные» детали.

Вот за это я и недолюбливаю все, что делает гугл: задумок хороших у них полно, но я пока не видел ни одного их продукта, который довели бы до состояния «не надо допиливать напильником».
Насколько знаю из своего опыта, на состояние проводной гарнитуры можно подписаться только из кода, а на состояние bluetooth-гарнитуры можно и в манифесте, при этом отпадает необходимость в разрешении android.permission.BLUETOOTH. Действительно, словно разные части писали разные группы, но в манах не нашёл, каким же образом разделяются интенты на местоположение регистратора (ну, кроме sticky — кроме него странностей достаточно).
Sign up to leave a comment.

Articles