Android длительная операция по обновлению appwidget - PullRequest
5 голосов
/ 14 декабря 2010

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

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

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

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

мысли

Ответы [ 2 ]

3 голосов
/ 15 декабря 2010

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

Да.

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

Да.

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

Ваш IntentService был прекрасным верным решением, ИМХО. Помните, что Android работает на медленных процессорах с устройствами с небольшим объемом оперативной памяти. Параллельно запускать множество потоков, как правило, не очень хорошая идея.

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

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

0 голосов
/ 14 декабря 2010

сделайте так, чтобы 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);
    }
}
...