2012-05-04 51 views
2

在一個活動中,我加載了需要很長時間的listview行,因此我將這個任務放在一個單獨的線程中以允許顯示progressDialog。在單獨的線程中填充listview

我做了以下

private void doMyStuff() { 
    listItems.clear(); 
    progressDialog.show(); 

    new Thread(new Runnable() { 
     @Override 
     public void run() {     
      for() { 
       listItems.add(something to add); 
      } 
     handler.sendEmptyMessage(0); 
     progressDialog.dismiss(); 
     } 
    }).start(); 
} 

private Handler handler = new Handler() { 
    public void handleMessage(android.os.Message msg) { 
     if (msg.what == 0) { 
      adapter.notifyDataSetChanged(); 
     } 
    }; 
}; 

我有時這引起了一個IllegalStateException的錯誤。首先我很驚訝,因爲編程線程就是我通常在標準Java程序中所做的。

該錯誤只出現「有時」,並且在逐步調試時不會出現。

這導致我在網上搜索,我發現了一些與此相關的問題,我必須承認事情並不清楚。

因爲我只有在線程完成時才調用notifyDataSetChanged(),爲什麼它有時會引發異常。

有人可以確認我這種做法是錯誤的,我必須使用異步任務,也許解釋我爲什麼?

我需要顯示一個progressDialog,有人可以給我一個AsyncTask的簡單例子,它填充一個listview並顯示填充進度的progressDialog。

感謝

UPDATE

jtanveer給我的答案的AsyncTask問題。現在其他人指出,解僱不在處理程序,我糾正。

據對「無痛線程」的jtanveer給出的文章,他們說,

Android提供了幾種方法來訪問其他線程UI線程它們中的哪一個是處理程序。

有人知道爲什麼在處理程序中放棄解僱沒有解決我的問題?對我來說listItem.add跟UI沒有關係?在這一點上我錯了嗎?

對我來說,在我的代碼中唯一的UI是adapter和progressdialog?任何評論或解釋是值得歡迎的。

最終答案

stjom給我具體的代碼工作的答案。在處理程序中運行runOnUiThread。它的工作,但我很驚訝,因爲我認爲處理程序運行在Ui線程...

感謝所有你的答案。

+1

我相信這裏有很多例子。嘗試在網上搜索「android progressdialog asynctask example」之類的東西。 – anon

+1

你現在的答案都是正確的。你不需要使用'AsyncTask',儘管它確實使這樣的操作變得乾淨。你必須做的是UI /主線程上的所有UI操作,這包括關閉進度對話框。你可以使用下面的'AsyncTask'例子,或者只在'Handler'回調中加入'progressDialog.dismiss()'。 – Devunwired

+0

+1給你們倆指出那個錯誤。不幸的是,它並沒有糾正我的問題,但我不明白爲什麼該處理程序是在UI線程中! – HpTerm

回答

2

無論何時您致電adapter.notifyDataSetChanged();它都會標識對您的listItems對象的任何更改。如果發現任何更改,它會相應地更新UI,我認爲這會導致您的問題。你可以撥打

runOnUiThread(new Runnable() { 
    public void run() { 
     adapter.notifyDataSetChanged(); 
    } 
}); 

在你的處理程序。

+1

+1它工作!但是你指出了一些對我來說不可理解的東西。怎麼處理程序沒有在UI線程中執行?我認爲這個處理程序是在UI線程中運行的。 – HpTerm

3

定義一個內部類象下面這樣:

,如果你需要,你可以參考這個article

+0

謝謝你花時間回答了這個問題。它工作正常,糾正我的錯誤。但我不明白爲什麼其他人的答案不起作用,因爲在處理程序中被解僱應該有正確的答案。 – HpTerm

+0

您正試圖從單獨的線程更新UI,這是嚴格禁止的。 UI更新必須從UI線程完成。也許這就是你得到例外的原因。 – jtanveer

+0

正如我所說我已經糾正了我的代碼,並在「處理程序」中解僱,這就是爲什麼現在我不明白爲什麼我仍然得到錯誤,而你的代碼工作正常 – HpTerm

2

你不需要使用AsyncTask,它只是一個方便。

至於爲什麼您當前的實現有時無法工作 - 您應該從UI線程中取消進度對話框,以便需要進入處理程序而不是後臺線程。

+0

+1用於指出錯誤。不幸的是,它並沒有糾正我的問題,但我不明白爲什麼,因爲就像你說的那樣,據我所知這僅僅是爲了「方便」,而且處理程序在UI線程中,我仍然不清楚。 – HpTerm