繁体   English   中英

刷新时listView随机崩溃

[英]listView crashed randomly when refresh

每当客户端(我的android应用)从服务器收到消息时,我都有一个listView刷新,但是问题是,当我在刷新按钮上单击很多次时,应用崩溃,并向我发送此错误: 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. Make sure your adapter calls notifyDataSetChanged() when its content changes. 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. Make sure your adapter calls notifyDataSetChanged() when its content changes.

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

活动代码:

 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);

        }
    });

}

Listfragment代码:

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:添加到列表

主线程: notifyDataSetChanged() [验证ListView,运行notifyDataSetChanged() runnable]

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

因此,如果这在您的逻辑上有效,则应执行此操作。

  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);

        }
    });

}

如错误消息所通知,您不能从非UI线程修改UI元素(您的Runnable使用单独的线程)。

使用Handler程序更新UI线程。 参见以下答案,例如: https : //stackoverflow.com/a/12717105/240646

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM