应用程序小部件appWidgetIds有问题(小部件的实际和虚拟实例)

10

同事们!我的问题是:我有一个带有配置活动的应用程序小部件(最低SDK-2.1),它能正常运行,但有时会开始变慢。我记录了日志并发现,在更新我的应用程序小部件之前,onUpdate方法会收到一组应用程序小部件ID。

  @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        Log.d("onUpdate", Arrays.toString(appWidgetIds));

但事实是,我在主屏幕上只有两个App小部件的实例,但数组的长度超过了2(两个):4、有时是5或6。怎么可能呢?我的AppWidget更新变慢的原因是,我必须为所有ID调用onUpdate方法,但有些ID(如某个人所说的“幽灵小部件”)不是真正的而且不正确。

也许,有人遇到过这样的问题,并会帮助我找出如何处理真正的应用程序小部件ID。

P.S. 卸载然后重新安装应用程序小部件(之后所有幽灵小部件都消失了)-并不是解决我的问题的适当方法。我想以编程方式控制幽灵和真正的小部件。

是否有人有解决这个bug的任何想法?


这是在安卓中比较常见的情况。据我所知,如果用户:1)放置了一个带有配置活动的小部件,并在完成之前退出该活动,或者2)尝试将小部件放置在没有足够空间的屏幕上,则会出现幽灵小部件。一旦创建了小部件,我不知道任何机制可以以编程方式检测它是否是“幽灵”小部件。 - Tim
谢谢您的评论...真遗憾... - Alex Zezekalo
3个回答

4

这段代码将会删除所有的小部件,甚至包括显示在屏幕上的小部件,因此并不是理想的解决方案。

ComponentName cn = new ComponentName(getApplicationContext(), YourWidget.class);
AppWidgetManager appWidgetManager =  AppWidgetManager.getInstance(getApplicationContext());
int[] appWidgetIds1 = appWidgetManager.getAppWidgetIds(cn);
AppWidgetHost host = new AppWidgetHost(getApplicationContext(), 0);
for (int appWidgetId : appWidgetIds1) {
    host.deleteAppWidgetId(appWidgetId);
}

仍然无法在4.2上删除锁屏小部件(onReceive从未被调用),您遇到了什么问题。

你有关于锁屏小部件中 onReceive 未被调用的解决方案吗? - BeNeXuS
很遗憾,我认为这是新SDK(4.2)的一个bug。目前我还没有解决方案。 - Alex Zezekalo
这段代码只是停止了对小部件的更新。然而,在重新启动模拟器后,小部件消失了(但在我的手机上没有)。 - einUsername

3

好的,我在网上搜索了一下,发现这似乎是一个普遍的安卓错误,目前还没有修复。如果可以的话,请尝试清除缓存。进入设置-->应用程序-->管理应用程序。然后进入您的主屏幕启动器应用程序并清除缓存。然后请重新启动您的应用程序,并查看是否仍有旧的应用程序小部件。我在网上找到了一些有趣的信息:

http://forum.xda-developers.com/showthread.php?t=1030804

http://eagle.phys.utk.edu/guidry/android/appWidget.html

即使在Android开发者页面和小组帖子中也讨论了这个问题。

http://developer.android.com/guide/topics/appwidgets/index.html#AppWidgetProvider

https://groups.google.com/forum/?fromgroups=#!msg/android-developers/Nl0e06rDCRY/4nAh3xnKBeQJ

他们谈论了1.5版本中的一个问题,但我认为即使在更高版本中也存在这个问题。在小组帖子中,有一个解决这个问题的示例:

      @Override
        public void onReceive(Context context, Intent intent) {
         final String action = intent.getAction();
         if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
         final int appWidgetId = extras.getInt
       (AppWidgetManager.EXTRA_APPWIDGET_ID,
            AppWidgetManager.INVALID_APPWIDGET_ID);
       if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
        this.onDeleted(context, new int[] { appWidgetId });
          }
       } else {
          super.onReceive(context, intent);
       }
      } 

似乎并不是每个应用小部件都会在用户删除应用或从主屏幕替换小部件时自动删除。如果这是正确的方向,请给我一些反馈。如果是,我们需要另一种方法来解决这个问题。对我来说也很有趣,但目前我没有笔记本电脑来检查它。谢谢。


到目前为止,我已经弄清楚了以下几点:1)对于主屏幕 - 在使用主页按钮退出配置活动时,这个错误会持续出现,但是当我尝试在没有空间的屏幕上放置小部件时(HTC Nexus One 2.1),它并没有复现。在我的情况下,清除缓存是不可能的,因为缓存= 0。2)对于锁定屏幕(Android 4.2)- 当我尝试从锁定屏幕中删除appwidget实例时,这个错误会持续出现。在这种情况下,它从未调用onReceive和onDelete方法 - 对于appWidgetProvider来说,这是奇怪的行为,不是吗? - Alex Zezekalo
示例中解决问题1.5对我来说不适用,因为:1)对于主屏幕-在添加小部件到主屏幕时出现错误,在删除时没有。2)对于锁定屏幕-确实在从锁定屏幕中删除窗口小部件时出现,但在这种情况下,onReceive方法不会被调用。 - Alex Zezekalo
非常奇怪。等我回家后,我会尝试解决这个问题。希望有办法解决它…… - Opiatefuchs
我也是,非常感谢你的帮助。 - Alex Zezekalo
我已在HTC Nexus One(SDK 2.1)和Asus Nexus 7(SDK 4.2)设备上进行了测试...确实,增加小部件ID对于你所描述的这种情况是正常的,但我的意思是增加appwidgetids数组的长度。如果你想重现这种错误,请按照我之前说的做法:1)对于主屏幕-使用主页按钮退出配置活动时,这个错误会持续出现;2)对于锁定屏幕-你应该有一台平板电脑(Nexus 7或10)并且安装了Android 4.2。在早期版本的SDK中,没有锁定屏幕小部件。现在我认为这是新SDK的一个错误。 - Alex Zezekalo
显示剩余3条评论

0

我之前写的一个应用程序也遇到了同样的问题,但在我的情况下并不重要。我找到了一个关于如何删除“幽灵小部件”的教程。我从未尝试过,你可以试试:

http://blog.fiziksphreak.com/2011/07/28/remove-phantom-widgets-in-android/

但是,你确定这会减慢你的应用程序吗?我无法想象这会消耗大量资源。

编辑

与其关闭旧应用程序,这可能会有所帮助:

    Bundle extras = intent.getExtras();
     int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);

或者

    Bundle extras = intent.getExtras();
     int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);

我不知道这是否是你要找的。


但是还有其他的决定吗? - Alex Zezekalo

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