Долгосрочная работа Android для обновления приложения

У меня есть виджет, который должен выполнять потенциально длительную операцию в onUpdate (). Просто выполнение операции напрямую привело к ANR. Чтобы решить эту проблему, моя первая попытка заключалась в создании в ней потока. Я заметил, что виджет не будет обновляться в некоторых случаях. Моя догадка заключается в том, что как только onUpdate () выйдет, андроид может убить процесс вместе с незавершенным потоком.

Моя следующая попытка заключалась в создании сервисной службы. Виджет onUpdate () просто запускает службу намерения, которая непосредственно выполняет работу и обновляет виджет, когда это делается. Это работает, но, к моему большому удивлению, кажется, что onHandleIntent () является однопоточным. Если у меня есть два виджета, а затем оба обновления и запуск службы намерения, они обновляются последовательно …

Два случая виджета не очень важны, но мне просто интересно узнать о лучшей практике для этого типа шаблонов.

Чтобы решить два случая виджета, я закончил обновление всех экземпляров виджета теми же данными всякий раз, когда кто-либо из них щелкнул. Например, я выполняю длительный процесс один раз и применяю результаты ко всем экземплярам виджета. В моем сценарии это не имеет значения, но для многих виджетов это может быть важно не делать.

мысли?

Но, к моему большому удивлению, похоже, что onHandleIntent () является однопоточным

Да.

Если у меня есть два виджета, а затем оба обновления и запуск службы намерения, они обновляются последовательно …

Да.

Но я просто задаюсь вопросом о лучшей практике для этого типа рисунка.

Ваш IntentService был прекрасным решением, IMHO. Помните, что Android работает на медленных процессорах, с устройствами с небольшой оперативной памятью. Запуск большого количества потоков параллельно, как правило, не очень хорошая идея.

То я начинаю тему в onHandleIntent (), которая требует блокировки следа, и кажется, что все становится слишком сложным.

Попробуйте мой WakefulIntentService .

Make onUpdate вызывать свою собственную функцию, чтобы циклически перемещаться по виджетам и обновлять их. Сделайте свою асинхронную задачу перед циклом. Вам понадобятся два отдельных действия, в которых предлагается начать обновление, и того, который будет транслировать ваш IntentService , чтобы позволить виджетам знать, что они закончены. Надеюсь это поможет.

  @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { updateWidget(context, appWidgetManager, appWidgetIds); } private void updateWidget(Context context){ ComponentName widget = new ComponentName(context, MyWidget.class); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(widget); updateWidget(context, appWidgetManager, appWidgetIds); } private void updateWidget(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final boolean isEnabled = true; //took out code didn't want you to see // start intent service here for(int i = 0; i< appWidgetIds.length; i++){ int appWidgetId = appWidgetIds[i]; Intent intent = new Intent(isEnabled ? ACTION_TOGGLE_OFF : ACTION_TOGGLE_ON); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); views.setOnClickPendingIntent(R.id.widget , pi); views.setImageViewResource(R.id.widget_image, isEnabled? R.drawable.widget_on : R.drawable.widget_off); appWidgetManager.updateAppWidget(appWidgetId, views); } }