为了账号安全,请及时绑定邮箱和手机立即绑定

Android,ListView IllegalStateException:

Android,ListView IllegalStateException:

qq_遁去的一_1 2019-08-03 07:03:26
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次插入一次,以避免闪烁和突然的列表变化。它不能这样做,总是通知适配器时,基本列表的变化。这个窃听器对我来说已经消失很久了。
查看完整描述

3 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

我也有过同样的问题。

我在我的ArrayList在UI线程之外。

解决办法:我两者都做过,adding the items并呼叫notifyDataSetChanged()在UI线程中。



查看完整回答
反对 回复 2019-08-05
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

我也有同样的问题,但是我用这个方法修复了它。

requestLayout();

从班上ListView


查看完整回答
反对 回复 2019-08-05
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

这是一个多线程正确发布和使用同步这是可以阻止的。不需要在UI线程上添加额外的内容,也不会导致应用程序的响应能力丧失。

我也面临着同样的问题。正如最被接受的答案所建议的那样,从UI线程更改适配器数据可以解决这个问题。这将有效,但是一个快速和容易的解决办法,但不是最好的。

你可以看到正常情况下。从后台线程更新数据适配器,并调用UI线程中的NotifyDataSetChanged。

当UI线程正在更新视图时,当另一个后台线程再次更改数据时,就会出现这个非法的StateException。这一时刻引起了这个问题。

因此,如果要同步所有正在更改适配器数据的代码,并进行通知数据更改调用。这个问题应该解决了。随着我的离去,我仍然在更新来自后台线程的数据。

下面是我的案例代码,供其他人参考。

主屏幕上的加载程序将电话簿联系人加载到后台的数据源中。

    @Override
    public Void loadInBackground() {
        Log.v(TAG, "Init loadings contacts");
        synchronized (SingleTonProvider.getInstance()) {
            PhoneBookManager.preparePhoneBookContacts(getContext());
        }
    }

这个PhoneBookManager.getPhoneBookContact读取电话簿中的联系人并将它们填充到hashmap中。它可直接用于列表适配器绘制列表。

我的屏幕上有个按钮。这就打开了一个活动,其中列出了这些电话号码。如果我在前面的线程完成其工作之前直接在列表上设置Adapter,即快速导航情况发生的次数较少。它弹出了例外。哪个是这个标题,所以问题。所以我必须在第二次活动中做这样的事情。

我在第二个活动中的加载器等待第一个线程完成。直到显示一个进度条。检查两个装载机的装载机后台。

然后,它创建适配器并将其传递给在UI线程上我称为setAdapter的活动。

解决了我的问题。

此代码仅为片段。您需要更改它,以便为您进行良好的编译。

@Overridepublic Loader<PhoneBookContactAdapter> onCreateLoader(int arg0, Bundle arg1) {
    return new PhoneBookContactLoader(this);}@Overridepublic void onLoadFinished(Loader<PhoneBookContactAdapter> 
    arg0, PhoneBookContactAdapter arg1) {
    contactList.setAdapter(adapter = arg1);}/*
 * AsyncLoader to load phonebook and notify the list once done.
 */private static class PhoneBookContactLoader extends AsyncTaskLoader<PhoneBookContactAdapter> {

    private PhoneBookContactAdapter adapter;

    public PhoneBookContactLoader(Context context) {
        super(context);
    }

    @Override
    public PhoneBookContactAdapter loadInBackground() {
        synchronized (SingleTonProvider.getInstance()) {
            return adapter = new PhoneBookContactAdapter(getContext());    
        }
    }}

希望这能帮上忙




查看完整回答
反对 回复 2019-08-05
  • 3 回答
  • 0 关注
  • 374 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信