Android学习笔记:ProgressDialog与多线程
在UI的线程中执行需要花费一些时间的后台操作,比如下载数据,会导致UI线程拖慢对用户操作做出响应。超过一段时间没有响应的Activity会被Android操作系统报告给用户,并询问用户希望结束程序还是继续等待。这显然是我们不希望的,后台的操作不应该导致前台操作被拖延。(想象一下,如果你用UI线程执行下载1GB数据的工作,那么在下载结束之前,用户甚至都没有点暂停的机会)
Java中一般解决这种问题的思路是是用Thread来创建新的线程执行后台操作,但这样在Android里面行不通。因为不允许在非UI线程上执行调用影响UI显示的函数,比如关闭对话框。官方对此的解释是,因为Android UI不是线程安全的,在非UI上执行UI操作会有concurrency的问题。Android为此提供了一个新的方法来解决这个问题,叫做AsyncTask。
通过重载AsyncTask的一些函数,我们可以在后台执行操作,并且在执行完成后在UI线程上执行另外的操作。以下是一个显示进度对话框,并执行后台任务,完成后关闭进度对话框的例子。
private ProgressDialog dialog;
// 此处省略这个class其他的函数
private void doSomething() {
dialog = ProgressDialog.show(this, “wait”, “something is in progress”);
dialog.setCancelable(false); //如果不希望用户在执行过程中用返回键关闭这个窗口,设置此项
new backgroundWorker().execute(param); //这里的param后面会发送给AsyncTask的doInBackground函数
……
}
private void backgroundDone() {
dialog.dismiss();
}
class backgroundWorker extends AsyncTask<Integer, Void, Boolean> {
//这三项分别是param,progress,result的类型,注意这里不能用int而要使用Integer,因为Integer是int的class版。Void也是一个道理
//三个类型具体可以根据实际情况选择,这里我们只是举例。
//doInBackground的参数类型必须是param的类型,返回值必须是result的类型
@Override
protected Boolean doInBackground(Integer… params) {
//这里的param就是刚才execute传入的参数
//do something in background
return true; //这里的返回值会发送给onPostExecute作为参数
}
//onPostExecute的参数类型必须是result的类型
@Override
protected void onPostExecute(Boolean result) {
backgroundDone();
}
}
doInBackground中的代码会在后台上新建一个线程执行,执行完成之后,onPostExecute会自动在UI线程上面执行。
为什么不能在doInBackground里面执行UI代码呢?既然backgroundWorker是一个new出来的object,并不跟UI在同一个实例中。要这么问的话。。。
亲,你该吃药了。。。。。
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Recent Comments
- Franny on 留言板
- jerry on UWaterloo的CS课程介绍,一篇充斥着淡淡忧伤的总结…..ˋ(╯ω╰)ˊ
- 上官小天 on UWaterloo的CS课程介绍,一篇充斥着淡淡忧伤的总结…..ˋ(╯ω╰)ˊ
- tooyoungtoosimple on UWaterloo的CS课程介绍,一篇充斥着淡淡忧伤的总结…..ˋ(╯ω╰)ˊ
- 上官小天 on UWaterloo的CS课程介绍,一篇充斥着淡淡忧伤的总结…..ˋ(╯ω╰)ˊ
Leave a Reply