android - 在这种情况下如何避免 IllegalStateException : The content of the adapter has changed but ListView did not receive a notification

标签 android multithreading listview adapter

我有 ListView这表明,通过 Adapter ,数据来自全局ArrayList .如果我想添加一个元素到这个 ArrayList正确的方法是在主 (UI) 线程中执行此操作并立即调用 Adapter.notifyDataSetChanged()之后,为了避免“IllegalStateException:适配器的内容已更改但ListView没有收到通知”。然而 ArrayList在辅助线程中更改,由 Service 执行它并不总是绑定(bind)到 Activity,因此并不总是引用 Adapter为了在主线程队列中发布这些操作。因此,当(我想)主线程运行到更改的列表中时,就会出现异常。

我看到了两种规避方法:

  • 使适配器全局化,以便我可以随时引用它。
  • 克隆列表并制作 Adapter由克隆支持。因此,当原始列表更改时,克隆将保持不变,直到主线程需要显示更改(例如在 Activity.onResume() 上),此时我根据原始列表更新克隆并调用 notifyDataSetChanged() .

  • 第二种方法的缺点似乎是明显不必要的冗余和内存开销(虽然列表不大,最多大约 500 个对象,每个对象 12 个字段)。我倾向于选择第一个,但你觉得哪个最好?如果有第三种方法,请告诉我。

    最佳答案

    由于您没有显示您的代码,我不知道这是否有帮助,但您是否考虑过使用 CountDownLatch ?手册页中提供了一个完美的例子,它阻止了线程的执行,直到 Latch 被释放。您可以简单地在主 Activity 中声明一个实例,并传递对 Service 和其他相关部分的引用。

    由于您的服务未绑定(bind),您可以使用 BroadcastReceiver将实例传递给服务,甚至使用 Semaphore相反,因为最后一个是可序列化的,因此可以作为一个额外的 Intent (不过,在这种情况下,您需要绑定(bind)服务)。

    关于android - 在这种情况下如何避免 IllegalStateException : The content of the adapter has changed but ListView did not receive a notification,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21113055/

    相关文章:

    multithreading - 门环内外互斥锁速度差异

    java - Android ListView 与 SimpleAdapter 泄漏内存

    android - 禁用 kapt 的增量构建

    android - 使用 iText 在 Android 中将文本转换为 PDF

    java - 将文件复制到 Assets 文件夹

    c# - Xamarin Forms 找不到如何将对象与详细信息 View 绑定(bind)

    android - Fragment不调用ListView的getView方法

    java - 扩展 Listadapter 时出现运行时错误

    ruby-on-rails - 如何在 Puma 中启用集群或混合模式,它们是什么?

    c++ - 多线程ifstream/ofstream