【发布时间】:2011-03-09 02:28:35
【问题描述】:
我想做的事:运行一个后台线程,计算 ListView 内容并部分更新 ListView,同时计算结果。
我知道我必须避免的事情:我不能弄乱后台线程中的 ListAdapter 内容,所以我继承了 AsyncTask 并从 onProgressUpdate 发布结果(向适配器添加条目)。我的适配器使用结果对象的 ArrayList,对这些 arraylist 的所有操作都是同步的。
其他人的研究:有非常有价值的数据here。对于大约 500 名用户,我几乎每天都会遇到崩溃,当我在 onProgressUpdate 中添加 list.setVisibility(GONE)/trackList.setVisibility(VISIBLE) 块时,崩溃降低了 10 倍,但并没有消失。 (建议在answer )
我有时会得到什么:请注意,这种情况很少发生(每周一次,对于 3.5k 用户之一)。但我想完全摆脱这个错误。这是部分堆栈跟踪:
`java.lang.IllegalStateException:` The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131296334, class android.widget.ListView) with Adapter(class com.transportoid.Tracks.TrackListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1432)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:2062)
at android.widget.ListView.onTouchEvent(ListView.java:3234)
at android.view.View.dispatchTouchEvent(View.java:3709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:852)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
[...]
帮助?不再需要,见下文
最终答案:事实证明,我每插入 5 次就调用一次notifyDataSetChanged,以避免闪烁和突然的列表更改。不能这样做,当基本列表发生变化时总是通知适配器。这个错误现在对我来说早已消失了。
【问题讨论】:
-
你调用 notifyDataSetChanged() 了吗?
-
当然,在 onProgressUpdate 中有顺序:list.setVisibility(GONE) - addObjectToList/listed 上的同步操作/ - notifyDataSetChanged() - list.setVisibility(VISIBLE) (并且没有可见性修改异常发生很远更频繁)
-
你是在不同的线程上修改底层的 ArrayList 吗?所有更改,甚至是适配器引用的 ArrayList,都必须在 UI 线程上发生。
-
@Qberticus - 正如我明确指出的,我不会从不同的线程修改 ArrayList,而是从 AcyncTask 的 onProgressUpdate 方法修改 - 它在 GUI 线程中工作。
-
@tomash 我遇到了同样的异常,我正在使用 pull 刷新并在执行后我写了 adapter.notifyDataSetChanged(); lvAutherlist.completeRefreshing(); 但有时会出现这个错误如何解决
标签: android exception listview adapter