Reputation: 8281
In an activity I load rows of a listview which takes much time, therefore I put this task in a separate thread to allow displaying a progressDialog.
I do the following
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();
}
};
};
I have sometimes a bug which raises an IllegalStateException. First of all I was surprised, because programming thread like that is what I usually do in standard Java programs.
The bug appears only "sometimes" and it does not appear when doing step by step debugging.
This lead me to search around the web and I found some questions in SO related to this and I must admit that things are not clear to my mind.
As I call the notifyDataSetChanged() only when the thread finished why does it sometimes raises an exception.
Can someone confirm me that this way of doing is wrong, and that I MUST use async task and perhaps explain me why ???
I need to have a progressDialog displayed, can someone give me a simple example of AsyncTask populating a listview AND displaying a progressDialog of the populating progress.
Thanks
UPDATE
jtanveer gave me the answer to the asynctask question. Now the others pointed out that the dismiss is not in the handler, which I correct.
According to the article given by jtanveer on "Painless Threading" they say that
Android offers several ways to access the UI thread from other threads which one of them is HANDLER.
Does someone know why putting the dismissed in the handler did not solve my problem ? for me listItem.add has nothing to do with UI ? Am I wrong on that point ?
For me, in my code the only UI is adapter and progressdialog ? Any commentary or explanation is welcome.
FINAL ANSWER
stjom gave a working answer for my specific code. Running the runOnUiThread in the handler. It's working but I am surprised because I thought the handler was run in the Ui Thread ...
Thanx to all for all your answers.
Upvotes: 3
Views: 8461
Reputation: 1112
whenever you call adapter.notifyDataSetChanged();
it identifies any changes to your listItems
object. if any change is found, it will update the UI accordingly which I think causes your problem. you can call
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});
inside your handler.
Upvotes: 2
Reputation: 1340
You don't need to use AsyncTask, its just a convenience.
As far as why your current implementation doesn't work sometimes - You should dismiss your progress dialog from the UI thread, so that needs to go in your handler, not your background thread.
Upvotes: 2
Reputation: 398
define an inner class like below:
private class LoadListTask extends AsyncTask<String, Void, Integer> {
protected void onPreExecute() {
progressDialog.show();
}
protected Integer doInBackground(String... params) {
for () {
listItems.add(something to add);
}
return 0;
}
protected void onPostExecute(Integer result) {
progressDialog.dismiss();
if (result == 0) {
adapter.notifyDataSetChanged();
}
}
}
if you need, you can refer to this article.
Upvotes: 3