簡體   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