猿问

Android,ListView IllegalStateException:

Android,ListView IllegalStateException:“适配器的内容已经更改,但ListView没有收到通知”

我想做什么:运行一个后台线程,该线程计算ListView内容并部分更新ListView,同时计算结果。

我知道我必须避免:我不能从后台线程处理ListAdapter内容,因此我继承了AsyncTask并从onProgressUpdate发布结果(向适配器添加条目)。我的Adapter使用结果对象的ArrayList,这些数组列表上的所有操作都是同步的。

他人研究*有非常有价值的数据这里..我还遭受了几乎每天对500名用户的崩溃,当我添加list.setVisibility(GONE)/trackList.setVisibility(VISIBLE)块在onProgressUpdate中,崩溃降低了10倍,但没有消失。(建议回答 )

我有的时候:请注意,这种情况很少发生(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)

[...]

帮助?不再需要了,见下面

最后答案:结果,我打电话给notifyDataSetChanged每5次插入一次,以避免闪烁和突然的列表变化。它不能这样做,总是通知适配器时,基本列表的变化。这个窃听器对我来说已经消失很久了。



qq_遁去的一_1
浏览 375回答 3
3回答

UYOU

我也有过同样的问题。我在我的ArrayList在UI线程之外。解决办法:我两者都做过,adding the items并呼叫notifyDataSetChanged()在UI线程中。

慕码人2483693

我也有同样的问题,但是我用这个方法修复了它。requestLayout();从班上ListView

宝慕林4294392

这是一个多线程正确发布和使用同步这是可以阻止的。不需要在UI线程上添加额外的内容,也不会导致应用程序的响应能力丧失。我也面临着同样的问题。正如最被接受的答案所建议的那样,从UI线程更改适配器数据可以解决这个问题。这将有效,但是一个快速和容易的解决办法,但不是最好的。你可以看到正常情况下。从后台线程更新数据适配器,并调用UI线程中的NotifyDataSetChanged。当UI线程正在更新视图时,当另一个后台线程再次更改数据时,就会出现这个非法的StateException。这一时刻引起了这个问题。因此,如果要同步所有正在更改适配器数据的代码,并进行通知数据更改调用。这个问题应该解决了。随着我的离去,我仍然在更新来自后台线程的数据。下面是我的案例代码,供其他人参考。主屏幕上的加载程序将电话簿联系人加载到后台的数据源中。&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Void&nbsp;loadInBackground()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.v(TAG,&nbsp;"Init&nbsp;loadings&nbsp;contacts"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synchronized&nbsp;(SingleTonProvider.getInstance())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PhoneBookManager.preparePhoneBookContacts(getContext()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}这个PhoneBookManager.getPhoneBookContact读取电话簿中的联系人并将它们填充到hashmap中。它可直接用于列表适配器绘制列表。我的屏幕上有个按钮。这就打开了一个活动,其中列出了这些电话号码。如果我在前面的线程完成其工作之前直接在列表上设置Adapter,即快速导航情况发生的次数较少。它弹出了例外。哪个是这个标题,所以问题。所以我必须在第二次活动中做这样的事情。我在第二个活动中的加载器等待第一个线程完成。直到显示一个进度条。检查两个装载机的装载机后台。然后,它创建适配器并将其传递给在UI线程上我称为setAdapter的活动。解决了我的问题。此代码仅为片段。您需要更改它,以便为您进行良好的编译。@Overridepublic&nbsp;Loader<PhoneBookContactAdapter>&nbsp;onCreateLoader(int&nbsp;arg0,&nbsp;Bundle&nbsp;arg1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;PhoneBookContactLoader(this);}@Overridepublic&nbsp;void&nbsp;onLoadFinished(Loader<PhoneBookContactAdapter>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;arg0,&nbsp;PhoneBookContactAdapter&nbsp;arg1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;contactList.setAdapter(adapter&nbsp;=&nbsp;arg1);}/* &nbsp;*&nbsp;AsyncLoader&nbsp;to&nbsp;load&nbsp;phonebook&nbsp;and&nbsp;notify&nbsp;the&nbsp;list&nbsp;once&nbsp;done. &nbsp;*/private&nbsp;static&nbsp;class&nbsp;PhoneBookContactLoader&nbsp;extends&nbsp;AsyncTaskLoader<PhoneBookContactAdapter>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;PhoneBookContactAdapter&nbsp;adapter; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;PhoneBookContactLoader(Context&nbsp;context)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(context); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;PhoneBookContactAdapter&nbsp;loadInBackground()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synchronized&nbsp;(SingleTonProvider.getInstance())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;adapter&nbsp;=&nbsp;new&nbsp;PhoneBookContactAdapter(getContext());&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}希望这能帮上忙
随时随地看视频慕课网APP

相关分类

Java
我要回答