【问题标题】:Android: Modifying adapter content from a background threadAndroid:从后台线程修改适配器内容
【发布时间】:2010-09-14 10:53:48
【问题描述】:

我已经阅读了很多关于使用 BaseAdapter 时引发的异常的信息,但我似乎找不到替代解决方案: 确保您的适配器的内容未被后台线程修改

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

当我的 ActivityListView 在前台,BaseAdapter 绑定到消息队列的数据时,问题就来了,并且消息来了在插座中。将新消息添加到队列中会抛出上述异常。除非我用消息队列预先填充我的 BaseAdapter(就像在 BaseAdapter 中拥有自己的消息队列一样)并在有新消息进入时更新它们,否则我真的找不到解决办法这个问题。

我真的不想像这样加倍努力保持这 2 个队列是最新的,肯定有更好的方法吗?发送广播也不起作用,因为适配器服务滚动和 notifyDataSetChanged 调用的潜在延迟。

【问题讨论】:

  • 您真正使用的是什么适配器?您确实意识到 BaseAdapter 是抽象的吧?另外,你有什么例外?你没有提到它。
  • 嗨,目前我只是通过扩展 BaseAdapter 创建自己的类,实现方法 getCount()、getItem()、getItemId() 和 getView();例外情况是上面提到的:“确保您的适配器的内容不是从后台线程修改的”。由尝试从非 ui 线程(在本例中为保存消息队列的控制器类)更新适配器的数据集引起。我正在尝试找到一种方法来更新我的消息队列以及 Activity(如果它在前台)。

标签: android listview android-activity


【解决方案1】:

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

【讨论】:

  • 我正在考虑这样做,但这意味着来自网络层的任何消息都必须被广播以便 Activity 接收。如果 Activity 不在前台(或在 Activity 堆栈中),则不会处理该消息。听起来对吗?
  • @Bundee:“但这意味着来自网络层的任何消息都必须被广播,以便 Activity 接收。” -- 原则上,你可以在Service 中使用Handler,虽然我没有尝试过。
  • 只是想问同样的问题,直到我意识到之前已经有人问过了。我可以确认 CommonsWare 解决方案有效。我在我的服务中使用了一个处理程序来修改一个适配器的内容。
【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 2014-08-24
    • 1970-01-01
    • 2020-04-18
    • 2014-05-28
    • 2016-04-29
    相关资源
    最近更新 更多