8

我有一个小部件需要在onUpdate(). 只是执行操作直接导致 ANR 的。为了解决这个问题,我的第一次尝试是在其中创建一个线程。我注意到小部件在某些情况下不会更新。我的猜测是,一旦onUpdate()退出,Android 可能会终止该进程以及未完成的线程。

我的下一个尝试是创建一个意图服务。小部件onUpdate()只是启动意图服务,该服务直接完成工作并在完成后更新小部件。这行得通,但令我惊讶的是,它似乎onHandleIntent()是单线程的。如果我有两个小部件,然后都更新并启动意图服务,它们会按顺序更新......

这两个小部件的情况并不重要,但我只是想知道这种模式的最佳实践。

为了解决这两个小部件的情况,我最终会在单击其中任何一个时使用相同的数据更新所有小部件实例。例如,我执行一次长时间运行的过程并将结果应用于所有小部件实例。在我的场景中,这无关紧要,但对于许多小部件,不这样做可能很重要。

想法?

4

2 回答 2

3

但令我惊讶的是,onHandleIntent() 似乎是单线程的

是的。

如果我有两个小部件,然后都更新并启动意图服务,它们会按顺序更新......

是的。

但我只是想知道这种模式的最佳实践。

恕我直言,您IntentService是一个很好的解决方案。请记住,Android 运行在速度较慢的 CPU 上,设备的 RAM 很少。并行运行大量线程通常不是一个好主意。

然后我开始在 onHandleIntent() 中启动一个线程,这需要一个唤醒锁,而且看起来它变得太复杂了。

试试我的WakefulIntentService.

于 2010-12-14T23:06:47.887 回答
0

让 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);
    }
}
于 2010-12-14T20:53:42.513 回答