java - listView 刷新时随机崩溃

标签 java android listview

我有一个 listView,每次客户端(我的 Android 应用程序)从服务器收到消息时都会刷新,但问题是当我多次单击刷新按钮时,应用程序崩溃并向我发送此错误:java.lang.IllegalStateException:适配器的内容已更改,但 ListView 未收到通知。确保适配器的内容不是从后台线程修改的,而是仅从 UI 线程修改的。确保您的适配器在其内容更改时调用notifyDataSetChanged()。

编辑1:崩溃不会每次都发生,只有当我快速单击刷新按钮大约十次时才会发生

Activity 代码:

 class receiveimplements Runnable {
    @Override
    public void run() {
        try {

            if (socket != null && socket.isConnected()) {

                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                for (; ; ) {
                    while ((textRecu = reader.readLine()) != null) {
                        if (textRecu.length() < 6) {
                            bug = true;
                            break;
                        }

                        Log.d("textrecuapres", textRecu);
                        index++;
                        if (index == 1) {
                            listTitre.add(0, textRecu);
                            sendListeAndMakeAffichage(listSource,listTitre);
                        } else if (index == 2) {
                            listSource.add(0, textRecu);
                            index = 0;
                        }
                    }
                }
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

public void sendListeAndMakeAffichage(final List<String> sourceList,final List<String> sourceTitre) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            fragmentListe.setListTitreAndListSource(sourceTitre, sourceList);

        }
    });

}

列表 fragment 代码:

public void setListTitreAndListSource(List<String> listTitre, List<String> listSource) {

    this.listTitre = listTitre;
    this.listSource = listSource;

    adapter.bind(listTitre);
    setListAdapter(adapter);
}

适配器代码:

  public void bind(List<String> model) {
    notifyDataSetChanged();
    listeTitre = model;
    notifyDataSetChanged();
}

最佳答案

当您添加到listTitre时,无需调用notifyDataSetChanged()

  if (index == 1) {
     listTitre.add(0, textRecu);
     sendListeAndMakeAffichage(listSource,listTitre);

这正在更改适配器的内容。您确实安排了对 notifyDataSetChanged() 的调用,但不能保证在 ListView 渲染之前安排调用,这将验证其状态。必须在与 notifyDataSetChanged() 调用相同的处理消息中操作适配器,以保证这一切在下一次渲染中立即发生。

所以现在你正在做:

线程 1: 添加到列表

主线程: 评估PendingMessages([验证ListView,可运行,调用notifyDataSetChanged()]

您必须在与更新适配器的部分相同的事件中修改适配器(并且它们都必须来自主线程)

因此,如果这符合您的逻辑,您应该这样做。

  if (index == 1) {
     sendListeAndMakeAffichage(listSource,listTitre, textRecu);
  } ....

然后在该方法内部:

public void sendListeAndMakeAffichage(final List<String> sourceList,final List<String> sourceTitre, final String newEntry) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            listTitre.add(newEntry); // Now we manipulate the list in this runnable
            // While the next call to the fragment will finish updating the adapter
            // and call notifyDataSetChanged()
            fragmentListe.setListTitreAndListSource(sourceTitre, sourceList);

        }
    });

}

关于java - listView 刷新时随机崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20873953/

相关文章:

java - 更改 Spring Boot 应用程序中对象的默认 json

android - 通过主题应用 buttonStyle 不起作用,直接应用完美

android - 如果我没有达到 64k 限制,为什么我需要启用 multidex?

android - 在 ListView 中使用通用图像加载器加载一次图像

android - 使用自定义 simpleCursorAdapter

java - 无法解析方法 'displayMessage(java.lang.String)'

java - session 超时后是否可以获取用户名/上次访问的页面

java - javax.websockets/Tyrus 中的线程

android - setSelectionFromTop 有时不起作用

android - 以编程方式切换复选框