На мой взгляд проблема "законченных" сложных фреймворков/библиотек в том что мир вокруг "не законченный". Но это уже наверное больше философский вопрос.
Если в целом всё устраивает, то вопросов больше нет. :)
Ага, тогда понятно. Тогда всё нормально, под условие выхода этот код вполне подходит.
У меня несколько другой опыт — обычно что-то загружаю на сервер, а не скачиваю с него. Отсюда и попытки внести не нужные исправления.
Тогда всё в порядке, я не прав. Моя идея была запустить задачу только если нужно что-то синхронизировать и отдать на откуп системе когда всё это выполниться. Т.е. использовать OneoffTask и возвращать RESULT_RESCHEDULE пока всё-таки не получиться синхронизироваться. Но если важен вызов каждые N секунд, тогда конечно нужно использовать PeriodicTask, только нужно добавить условие выхода из цикла обновления, а то вызов каждые 30 секунд даже когда обновлять не нужно — выглядит не очень правильно.
Под "gap" я подразумевал окно в которое может быть вызвана задача, для PeriodicTask это устанавливается методом setFlex. Лучше задавать окна, это поможет системе группировать выполнение различных задач и будить устройство немного реже.
Итак, сразу бросается в глаза странное использование GcmNetworkManager. Фактически он сейчас заменяет простой AlarmManager. Хотелось бы чтобы он всё-таки использовался по назначению.
Задача явно должна быть не PeriodicTask. И тогда если она завершилась с ошибкой достаточно будет вернуть RESULT_RESCHEDULE. Система всё сделает самостоятельно её перезапустит в соответсвии с back-off policy. Я бы делал, например, 3 запроса подряд и возвращал RESULT_RESCHEDULE если всё плохо.
Также было бы замечательно добавить к задаче gap (flex или большой setExecutionWindow) для выполнения. А также setUpdateCurrent(true) для того чтобы не плодить несколько задач по ошибке. Как легко можно сделать сейчас, выходя и заходя в приложение снова.
По общей структуре:
Допустим что серия из 20 вызовов это бизнес требование, тогда, мне кажется, что лучше это делать в одном вызове IntentService. Зачем эта петля с созданием «broadcast <> service <> broadcast» не совсем понятно.
Дублирование кода в сервисах нужно убрать, это ни к чему хорошему не приводит.
Вызывать Thread.sleep в MainThread (MyBroadRec.onReceive) не самая лучшая идея.
Если уж используете broadcast, то желательно использовать LocalBroadcastManager.
Написал несколько сумбурно и урывками, т.к. достаточно неудобно это делать после статьи. Pull-request на порядок удобнее, даже несмотря на отсутствие навигации по коду (конечно исключая upsource).
В общем, все стало немного лучше. Можно даже сказать — идём правильно дорогой… но пока что на руках и забираем немного в сторону.
На мой взгляд идея правильная, просто неправильно выбраны средства для «синхронизации». Для решения проблемы с перезапуском загрузки я бы рассмотрел варианты:
простой — JobScheduler (Android 5+) или GcmNetworkManager (если нужна поддержка Android < 5). Проблема с GcmNetworkManager — это необходимость наличия play services на устройстве.
У меня замечательно заходит. И не просто заходит, а даже даёт зарегистрироваться и получить доступ к «кабинет разработчика приложений beta».
Что характерно регистрация пока что бесплатная.
Внутренние платежи могут проходить не через сервисы Google, если покупается:
— что-то реальное.
— цифровой материал, который может быть использован вне приложения.
На мой взгляд проблема "законченных" сложных фреймворков/библиотек в том что мир вокруг "не законченный". Но это уже наверное больше философский вопрос.
Если в целом всё устраивает, то вопросов больше нет. :)
Воу-воу. Я же просто троль. Нинада так серьёзно. :(
По поводу runtime DI особых возражений нет. Как-то с RoboGuice (иногда был чистый reflection), и с Dagger 1 жили. Да и сейчас с Koin живём. :)
Кстати, по поводу рисков есть вопрос. Мне кажется что Toothpick сейчас выглядит как abandonware.
Есть ли у вас планы что делать если он совсем загнётся (скажем в течении двух лет)?
Возьметё его поддержку на себя (fork) или перелезете на Dagger/Koin/Kodein? Или будет какой-то свой DI/Service-locator?
Как использовать runtime DI. :)
Ага, тогда понятно. Тогда всё нормально, под условие выхода этот код вполне подходит.
У меня несколько другой опыт — обычно что-то загружаю на сервер, а не скачиваю с него. Отсюда и попытки внести не нужные исправления.
Тогда всё в порядке, я не прав. Моя идея была запустить задачу только если нужно что-то синхронизировать и отдать на откуп системе когда всё это выполниться. Т.е. использовать
OneoffTask
и возвращатьRESULT_RESCHEDULE
пока всё-таки не получиться синхронизироваться. Но если важен вызов каждые N секунд, тогда конечно нужно использоватьPeriodicTask
, только нужно добавить условие выхода из цикла обновления, а то вызов каждые 30 секунд даже когда обновлять не нужно — выглядит не очень правильно.Под "gap" я подразумевал окно в которое может быть вызвана задача, для
PeriodicTask
это устанавливается методомsetFlex
. Лучше задавать окна, это поможет системе группировать выполнение различных задач и будить устройство немного реже.По общей структуре:
Написал несколько сумбурно и урывками, т.к. достаточно неудобно это делать после статьи. Pull-request на порядок удобнее, даже несмотря на отсутствие навигации по коду (конечно исключая upsource).
В общем, все стало немного лучше. Можно даже сказать — идём правильно дорогой… но пока что на руках и забираем немного в сторону.
Что характерно регистрация пока что бесплатная.
— что-то реальное.
— цифровой материал, который может быть использован вне приложения.