Android应用程序小部件无法从活动中更新

10

我有一个简单的appwidget,并且当在同一个应用程序中的活动中发生操作时,我想要更新它。在onUpdate()中,我立即更新小部件,这很好用。在我的活动中,我调用与onUpdate()中调用的相同静态更新方法的appwidget来更新视图。但是小部件没有被更新。

我可以跟踪代码直到AppWidgetManager.updateAppWidget()方法,并且所有这些都很好,但小部件没有更新。

我唯一可能看到的区别是从活动的上下文和appwidget的onUpdate()方法的上下文中调用的静态更新方法传递的上下文对象不同。然而,在网上有许多这样的例子,所以我认为它应该可以工作。

2个回答

23

我不确定你的代码是怎么写的,但是这是我使用的方法。在我的Activity中,我有以下方法:

private void updateAllWidgets(){
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(this, MyWidget.class));
    if (appWidgetIds.length > 0) {
        new MyWidget().onUpdate(this, appWidgetManager, appWidgetIds);
    }
}

我可以从我的Activity中的任何地方调用此方法来更新所有应用小部件,其中MyWidget是appwidget的类。


1
那个东西让事情运作起来了,所以问题肯定是我没有更新正确的ID。实际上,这个小部件使用它的ID设置了一个onclick意图,该意图被活动接收,然后告诉小部件更新自己。 - Jeffrey Blattman
我认为调用 onUpdate 方法并不是正确的方法,你应该发送一个广播来更新小部件,使用 AppWidgetManager.ACTION_APPWIDGET_UPDATE。 - midhunhk
从“正确的方法”角度来看,我同意你的观点,即发送广播是正确的方法。从“让它工作”的角度来看,上述方法会导致应用程序小部件更新-虽然有些不规范但是功能正常。 - dave.c
@dave.c,是的,你说得对。这种方法应该可以工作,但由于它是API的一部分,我认为我们最好允许平台调用onUpdate()方法。不能保证平台在调用onUpdate()方法之前不会执行其他操作。在这种情况下可能会出现其他问题。 - midhunhk

10

不要使用静态方法,利用小部件已经是广播接收器的事实,在清单文件中注册更新意图。然后每当您需要从活动更新它时,只需调用

//in your activity
sendBroadcast(new Intent(MyWidget.ACTION_UPDATE).putExtra(whatever));  



//In widget class
public static final String ACTION_UPDATE = "com.example.UPDATE_MY_WIDGET";

并且需要在您清单文件的接收者标签内部

<intent-filter>
  <action android:name="com.example.UPDATE_MY_WIDGET"/>
</intent-filter>

我之前是这样做的,但是我改成了小部件只启动一个意图服务。为什么呢?因为小部件执行的操作可能会比较长时间。当 onUpdate() 方法没有及时返回时,我在小部件中遇到了 ANR 的问题。不确定这是否与我的问题有关。 - Jeffrey Blattman
是的,任何长时间运行的操作都应该使用IntentService、AsyncTask或其他类型的线程。我的答案是关于如何通知您的小部件开始任务或者通知您的小部件任务已经完成并需要更新其状态的方法。 - Nathan Schwermann
很久以前的事情了,但是你应该在onUpdate()中启动一个服务来执行长时间操作。我认为接收器大约有5秒钟的执行时间。创建AsyncTask是不够的,因为当接收器被销毁时,它也会被杀死。 - HGPB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接