2012-05-04 50 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