【发布时间】:2011-02-14 03:00:47
【问题描述】:
我遇到了 IllegalStateException,将基础列表更新为适配器(可能是 ArrayAdapter 或 BaseAdapter 的扩展,我不记得了)。我目前没有或不记得异常的文本,但它说明了列表内容更改的效果,而适配器没有收到更改通知。
此列表/可能/从 UI 线程(主)以外的另一个线程更新。更新此列表(添加项目)后,我调用 notifyDataSetChanged。问题似乎是适配器或附加到适配器的 ListView 在调用此方法之前尝试更新自身。发生这种情况时,会抛出 IllegalStateException。
如果我在更新前将 ListView 的可见性设置为 GONE,然后再次 VISIBLE,则不会发生错误。但这并不总是可行的。
我在某处读到您无法从另一个线程修改底层 this ——这似乎限制了 MVC 模式,就像这个特定的列表一样,我想添加来自不同线程的项目。我假设只要调用 notifyDataSetChanged() 就安全了——适配器在调用此方法之前不会重新访问底层 List,但事实并非如此。
我想我要问的是,从 UI 以外的线程更新底层 List 是否安全?此外,如果我想修改适配器中的数据,我是修改底层列表还是适配器本身(通过其 add() 等方法)。通过Adapter修改数据好像不对。
我在另一个网站上遇到了一个似乎与我有类似问题的人的帖子:http://osdir.com/ml/Android-Developers/2010-04/msg01199.html(这是我从那里获得 Visibility.GONE 和 .VISIBLE 想法的地方)。
为了让您更好地了解我的特定问题,我将描述一下我的列表、适配器等是如何设置的。
我有一个名为 Queue 的对象,其中包含一个 LinkedList。 Queue 扩展了 Observable,当通过其方法将事物添加到其内部列表时,我调用 setChanged() 和 notifyListeners()。此 Queue 对象可以在任意数量的线程中添加或删除项目。
我有一个包含适配器的“队列视图”活动。此 Activity 在其 onCreate() 方法中向我的 Queue 对象注册了一个 Observer 侦听器。在 Observer 的 update() 方法中,我在 Adapter 上调用 notifyDataSetChanged()。
我添加了很多日志输出,并确定当这个 IllegalStateExcption 发生时,我的 Observer 回调从未被调用。所以就好像 Adapter 在 Observer 有机会通知它的 Observers 之前就注意到了 List 的变化,并调用我的方法通知 Adapter 内容发生了变化。
所以我想我要问的是,这是装配适配器的好方法吗?这是一个问题,因为我正在从 UI 线程以外的线程更新适配器的内容吗?如果是这种情况,我可能会想到一个解决方案(在创建 Queue 对象时为 UI 线程提供一个 Handler,并使用该 Handler 进行所有 List 修改,但这似乎不合适)。
我意识到这是一篇非常开放式的帖子,但我对此有点迷茫,如果有任何关于我所写内容的 cmets,我将不胜感激。
【问题讨论】:
标签: android