在一个活动中,我加载了listview的行,这需要花费很多时间,因此我将此任务放在一个单独的线程中以允许显示progressDialog。
我做以下
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程序中通常所做的。
该错误仅在“有时”出现,并且在逐步调试时不会出现。
这引导我在网上搜索,我在SO中发现了一些与此相关的问题,我必须承认事情并不清楚。
因为我只在线程结束时才调用notifyDataSetChanged(),为什么它有时会引发异常。
有人可以向我证实这种做法是错误的,我必须使用异步任务,也许可以解释一下为什么???
我需要显示progressDialog,有人可以给我一个简单的AsyncTask示例,用于填充列表视图并显示填充进度的progressDialog。
由于
更新
jtanveer给了我asynctask问题的答案。现在其他人指出解雇不在处理程序中,我纠正了。
根据jtanveer关于“无痛线程”的文章,他们说
Android提供了几种从其他线程访问UI线程的方法,其中一个是HANDLER。
有人知道为什么把被解雇者放入处理程序并没有解决我的问题吗?对我来说listItem.add与UI无关?我错了吗?
对我来说,在我的代码中,唯一的UI是适配器和progressdialog?欢迎任何评论或解释。
最终答案
stjom为我的具体代码提供了有效的答案。在处理程序中运行runOnUiThread。它工作但我很惊讶,因为我认为处理程序是在Ui线程中运行的......
感谢所有人的所有答案。
答案 0 :(得分:3)
定义一个内部类,如下所示:
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();
}
}
}
如果您需要,可以参考此article。
答案 1 :(得分:2)
您不需要使用AsyncTask,只是方便。
至于为什么你当前的实现有时不起作用 - 你应该从UI线程中删除你的进度对话框,这样就需要进入你的处理程序,而不是你的后台线程。
答案 2 :(得分:2)
每当您致电adapter.notifyDataSetChanged();
时,它都会识别您listItems
个对象的所有更改。如果发现任何更改,它将相应地更新UI,我认为这会导致您的问题。你可以打电话
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});
在你的处理程序中。