3

在一个活动中,我加载需要花费大量时间的列表视图的行,因此我将此任务放在单独的线程中以允许显示进度对话框。

我执行以下操作

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 关于“Painless Threading”的文章,他们说

Android 提供了几种从其他线程访问 UI 线程的方法,其中一种是 HANDLER。

有人知道为什么将被解雇的处理程序没有解决我的问题吗?对我来说 listItem.add 与 UI 无关?在这一点上我错了吗?

对我来说,在我的代码中,唯一的 UI 是 adapter 和 progressdialog ?欢迎任何评论或解释。

最终答案

stjom 为我的特定代码提供了一个有效的答案。在处理程序中运行 runOnUiThread。它正在工作,但我很惊讶,因为我认为处理程序是在 Ui 线程中运行的......

感谢大家的所有回答。

4

3 回答 3

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

如果需要,可以参考这篇文章

于 2012-05-04T20:26:53.270 回答
2

每当您调用它时,它都会识别您的对象adapter.notifyDataSetChanged();的任何更改。listItems如果发现任何更改,它将相应地更新 UI,我认为这会导致您的问题。你可以打电话

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

在您的处理程序内部。

于 2012-05-09T01:50:36.000 回答
2

您不需要使用 AsyncTask,它只是一种方便。

至于为什么您当前的实现有时不起作用 - 您应该从 UI 线程中关闭您的进度对话框,因此需要进入您的处理程序,而不是您的后台线程。

于 2012-05-04T22:10:45.577 回答