如何正确地使用android中的progressdialog




 

网上有很多关于progressdialog的用法的介绍,其核心代码:

复制代码
Handler handler = new Handler();  
 Runnable mTasks = new Runnable() {  
   public void run() {  
    //执行url获取内容操作
     }  
  };  
  final ProgressDialog myDialog = ProgressDialog.show(YourClass.this, "正在连接服务器..", "连接中,请稍后..", true, true);  
  handler.post(mTasks); 
复制代码

我实际使用后的效果是:点击按钮后(我是把这一系列操作放在一个clicklistener里)UI界面就阻塞在那里,然后等task执行完毕之后才显示progressdialog并且一直会存在(当然如果你在这个task结束后添加一条dialog.dismiss语句就会发现progressdialog显示后立即就消失了,但是这个不是本文的重点)我在stackoverflow上发现不少人有同样的问题,但是并没有找到正确的答案,只是有人给出了asynctask类的方案(我没有实际使用这个方案,但是根据我最后的理解,这种方案应该也是可行的)

这个问题困扰了我一个下午的时间,要解释这个问题,就要简单说一下android的UI线程,android程序启动时,会启动一个对应的主线程(就是UI线程),这个线程负责和用户的交互(例如按下按钮,滑动等),我们只能在UI线程中访问android UI 工具包。但是对于一些很耗时的操作,如果我们在主线程里完成的话,主线程就不能响应用户的操作,这样就会产生类似windows程序失去响应的效果,所以大部分时候我们都会启动一个新的线程执行这些操作,但是要注意在新的线程里是不能修改UI界面的(只能在UI线程里修改UI界面)。比如说我们想下载一个url的html内容,然后显示在界面的一个Textview上,我们如果在新启动的线程里调用textview.settext()方法是不会生效的。

说了这么多,是为了说明handler的作用就是为了在其他线程里更新UI。比如我们如果用handler.post(run) (run的内容就是更新在textview)的话,就可以实现我们的目的。

回到正题,我们如果按照前述代码使用progressdialog的话,在执行完

final ProgressDialog myDialog = ProgressDialog.show(YourClass.this, "正在连接服务器..", "连接中,请稍后..", true, true);

这条语句之后

handler.post(mTasks);

这条语句虽然看起来是在mtask这个线程里执行,但是因为使用了handler类,所以效果实际还是等同于阻塞了UI线程。所以progressdialog就等到mtask执行完毕之后才显示了。因此我们正确的写法应该是这样的:

复制代码
final ProgressDialog myDialog = ProgressDialog.show(YourClass.this, "正在连接服务器..", "连接中,请稍后..", true, true);  
   new Thread(){
   public void run() {  
     //执行url获取内容操作
             handle.post( //在这里面更新textview);
     }  
  }.start();
复制代码

最后如果希望在新线程执行完之后让progressdialog自动消失的话,就在新线程里利用handler执行dialog.dismiss()。这个内容在本文开头的链接里也有详细的介绍,在这里就不赘述了。

猜你喜欢

转载自z1han.iteye.com/blog/1890492