Как правильно обновить виджет в Android 8.0 - Oreo - API 26
Скажем, у меня есть виджет для приложения, у которого targetSDKVersion установлено значение 26. Этот виджет занимает от 100 мс до 10 секунд для обновления. Большую часть времени в возрасте до 1 года. Перед Android O, если onUpdate() был вызван на моем AppWidgetProvider, я мог бы запустить фоновый сервис для обновления этого виджета. Тем не менее, Android O возвращает исключение IllegalStateException, если вы попытаетесь выполнить это поведение. Очевидное решение о начале работы переднего плана кажется крайней мерой для чего-то, что будет сделано менее чем за 10 секунд в 99% случаев.
Возможные решения
- Запустите службу переднего плана для обновления виджета. Аноним пользователя с уведомлением, которое исчезнет через 10 секунд.
- Используйте JobScheduler для планирования работы как можно быстрее. Ваш виджет может или не может обновиться некоторое время.
- Попытка выполнить работу в широковещательном приемнике. Заблокируйте поток пользовательского интерфейса для любых других приложений. Тьфу.
- Попытка выполнить работу в приемнике виджетов. Заблокируйте поток пользовательского интерфейса для любых других приложений. Тьфу.
- Пожаловаться на GCM, чтобы запустить фоновый сервис. Много работы и чувствует себя взломанным.
Мне лично не нравится какое-либо из вышеперечисленных решений. Надеюсь, я что-то упустил.
(Еще больше разочаровывает то, что мое приложение уже загружено в память системным вызовом onUpdate(). Я не вижу, как загружать мое приложение в память, чтобы вызывать onUpdate(), но затем не давая обновлению моего приложения 1s виджет с потоком пользовательского интерфейса обеспечивает сохранение любого времени автономной работы.)
Ответы
Ответ 1
Вы не указываете, что такое механизм запуска обновления. Вы, похоже, обеспокоены задержкой ( "Ваш виджет может или не может быть обновлен какое-то время" ), поэтому я собираюсь предположить, что ваша заинтересованность связана с взаимодействием с виджетами приложения, например нажатием кнопки.
Используйте JobScheduler для планирования работы как можно быстрее. Ваш виджет может или не может обновиться некоторое время.
Это вариант "use JobIntentService
", который AFAIK является рекомендуемым решением для такого рода сценариев.
Другие варианты:
-
Используйте getForegroundService()
с PendingIntent
. При этом вы эффективно "мизинец ругаетесь", что ваша служба вызовет startForeground()
в пределах временного интервала ANR. Если работа занимает больше нескольких секунд, вызовите startForeground()
, чтобы убедиться, что Android не запутался. Это должно свести к минимуму количество времени, когда появляется уведомление переднего плана. И если пользователь нажал кнопку, и вы все еще заняты работой несколько секунд спустя, вы, вероятно, захотите показать уведомление или иначе сделать что-то, чтобы пользователь знал, что все, что они просят, все еще продолжается.
-
Используйте goAsync()
on BroadcastReceiver
, чтобы выполнять работу в контексте получателя, не связывая основной поток приложения. Я не пробовал это с Android 8.0+, поэтому YMMV.