2010-12-19 46 views
1

我正在写一个应用程序部件,我打算用项目列表填充。我试图通过扩展AppWidgetProvider来简单实现。我看到一些奇怪的行为,其中项目列表被添加到父窗口小部件两次。Android应用程序部件:添加了两次内容

下面的代码:

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    Log.i("MyApp", "onUpdate called"); 

    DbAdapter dbAdapter = new DbAdapter(context); 
    dbAdapter.open(); 

    final String[] columns = { DbTableCategory.KEY_NAME, DbTableCategory.KEY_CURRENTBAL }; 
    Cursor cursor = dbAdapter.getDb().query(DbTableCategory.TABLE_NAME, columns, null, 
         null, null, null, null); 

    final int n = appWidgetIds.length; 
    for (int i = 0; i < n; i++) { 

     Log.i("MyApp", "Widget instance " + i); 

     final int NUM_ITEMS = 4; 

     int id = appWidgetIds[i]; 
     RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 

     for (int c = 0; c < NUM_ITEMS; c++) { 

      // get item info from db 
      if (cursor.moveToPosition(c)) { 
       RemoteViews itemView = new RemoteViews(context.getPackageName(), R.layout.widget_item); 
       itemView.setTextViewText(R.id.widget_item_name, cursor.getString(0)); 
       itemView.setTextViewText(R.id.widget_item_amnt, cursor.getString(1)); 

       Log.i("MyApp", "Adding subview for item " + c); 
       rv.addView(R.id.widget_container, itemView); 
      } 
     } 

     appWidgetManager.updateAppWidget(id, rv); 
    } 

    cursor.close(); 
    dbAdapter.close(); 

我添加四个项目的名单,但我居然看到小部件八个项目(两次出现相同的四个)。从日志输出中,它告诉我该小部件有两个实例(根据appWidgetIds数组,并且ID不同),所以外部循环运行两次,并且内部循环(针对每个项目)正在运行如预期的四倍。我不明白这一点,因为我很积极,我只在主屏幕上添加了一次。它不在任何其他主屏幕上 - 我使用的是默认的HTC Sense启动器。

即使我已经实例化了两次小部件,我还是为每个小部件实例创建了一个新的RemoteViews。我只是不明白为什么一个小部件实例似乎收到两批的物品。我错了什么?

附录:当我在模拟器中运行完全相同的代码时,它工作得很好,只报告一个小部件实例。它只是显示实际手机上的奇怪行为(HTC Desire,Froyo)。

编辑:我因为在documentation注意到这个为RemoteViews.addView()

在RemoteViews的消费者可以回收布局的情况下,使用removeAllViews(INT)以清除任何现有的儿童。

难道是从RemoteViews(...)构造函数返回同一个RemoteViews实例吗?这可以解释为什么孩子的意见被添加两次,但它会而不是解释为什么似乎有两个实例摆在首位。

+0

您是否尝试在该方法中放置断点或打印出堆栈跟踪以查看它是如何被调用的?听起来像Sense UI的家庭活动与其他人有点不同。您可能会尝试找到其他小部件开发人员,看看他们是否遇到过这个问题。我自己从未制作过一个小部件。您也可以尝试使用其他设备,看看您是否可以将其缩小到HTC Sense UI。我也发现你不检查身份证。他们是一样的吗?如果是这样,这将是愚蠢的,但它会解释一些事情。 – 2010-12-27 04:53:35

+0

这些ID是不同的。 – 2010-12-28 13:00:07

回答

3

有关您的小部件返回两个appWidgetIds的第一个问题: 当小部件崩溃时(特别是在配置屏幕上或小部件完全放置之前),我遇到了类似的情况。桌面应用程序仍将包含关于它的信息,但不会显示它。

第二个(主要)问题可能是由布局视图的回收造成的,我的猜测是R.id.widget_container未被清理。所以你可能应该打电话:

rv.removeAllViews(R.id.widget_container); 

for循环之前。另外,我建议从光标(cursor.getCount())获取返回的行数,而不是对其进行硬编码(在您的代码中为NUM_ITEMS = 4)。

+0

我认为你是对的。在彻底清除手机中的应用程序和小部件的所有痕迹并重建和重新安装后,它不再报告两个小部件实例。调用rv.removeAllViews()也意味着这些项目只添加一次。 – 2010-12-28 20:33:49

0

我遇到了同样的问题,我的解决方案是从widget_container中删除任何内部子项,因为当调用rv.removeAllViews(R.id.widget_container);时,容器应该最初没有子项以避免发生冲突。

相关问题