2010-09-14 25 views
2

我读过很多关于使用BaseAdapter时抛出的异常,但我似乎无法找到替代解决方案: 请确保您的适配器的内容是没有从后台线程修改Android:从后台线程修改适配器内容

我想实现的是在内存中保留一个消息队列的副本,并使用此消息队列为我的ListView填充BaseAdapter。这样做的原因是,即使ListView当前不存在(例如聊天窗口),消息队列也会继续从套接字获取消息。

问题是当我有活动的ListView在前台,BaseAdapter绑定到消息队列的数据,并且一个消息到达在插座中。将新消息添加到队列中将引发上述异常。除非我预先填充我的BaseAdapter与消息队列(如在BaseAdapter有它自己的消息队列)并更新他们两个,当一个新的消息进来,我真的找不到解决此问题的方法。

我真的不想把这两个队列保持最新状态的努力翻倍,当然有更好的方法来做到这一点?发送广播无法正常工作,原因可能是由于适配器服务滚动的潜在延迟以及进行了notifyDataSetChanged调用。

+0

什么适配器,你真的使用?你知道BaseAdapter是抽象的吗?另外,你会得到什么例外?你没有提到它。 – codinguser 2010-09-14 11:45:22

+0

嗨,目前我只是通过扩展BaseAdapter创建我自己的类,实现getCount(),getItem(),getItemId()和getView()方法;上述情况除外:“请确保您的适配器的内容未被后台线程修改”。试图从非ui线程更新适配器的数据集(在本例中,我的控制器类持有消息队列)导致此问题。我试图找到一种方法来保持我的消息队列更新以及活动(如果它在前台)。 – Bundeeteddee 2010-09-14 15:14:09

回答

2

使用Handler修改主应用程序线程中的“消息队列”。

+0

我正在考虑这样做,但这意味着来自网络层的任何消息都必须广播才能使活动提取。如果活动不在前台(或活动堆栈中),则不会处理该消息。这听起来是对的吗? – Bundeeteddee 2010-09-14 15:07:51

+1

@Bundee:“但这意味着来自网络层的任何消息将不得不播放,以便活动提取。” - 原则上,你可以在'Service'中使用'Handler'来做这件事,尽管我还没有尝试过。 – CommonsWare 2010-09-14 15:24:08

+0

只是想问同样的问题,直到我意识到它已经被问过。我可以确认CommonsWare解决方案的工作原理。我在我的Serivce中使用了一个Handler来修改适配器的内容。 – M2X 2012-04-22 21:32:04

2

我也有这个问题。事实证明,我正在重新创建我的适配器的新数据,但旧的适配器仍然设置为列表视图,偶尔会导致崩溃。所以当我需要重新创建适配器时,我会这样做:

//Clear adapter's array 
if (!array.isEmpty()) { array.clear(); } 
if (adapter != null) { adapter = null; } 
setListAdapter(adapter); 

//Later code 
//array gets repopulated 
//adapter gets recreated 
setListAdapter(adapter); 
相关问题