Android 更新ProgressBar

来源:互联网 发布:天刀离玉堂捏脸数据 编辑:程序博客网 时间:2024/06/05 09:32

现在我们通过一个更新ProgressBar的小案例来学习下Android的UI更新和消息机制。

如下图,点击“Start”按钮,进度条开始变化。



 第一步:如下代码:

 

Java代码  收藏代码
  1. btnStart.setOnClickListener(new View.OnClickListener() {  
  2.             @Override  
  3.             public void onClick(View v) {  
  4.                 for (int i = 0; i <= 100; i = i + 10) {  
  5.                     bar.setProgress(i);  
  6.                     try {  
  7.                         Thread.sleep(1000);//每隔1S更新Bar  
  8.                     } catch (InterruptedException e) {  
  9.                         e.printStackTrace();  
  10.                     }  
  11.                 }  
  12.             }  
  13.         });  

 我们发现,

 

并没有进度条递变的效果,而是start按钮一直被占用,其他的任何操作都被阻塞了,还有可能报ANR。

因为只有一个主线程,而更新进度条是个耗时操作,程序就会暂时阻塞,所有我们可以另起一个线程来处理UI更新问题。

 

Java代码  收藏代码
  1. btnStart.setOnClickListener(new View.OnClickListener() {  
  2.     @Override  
  3.     public void onClick(View v) {  
  4.         new Thread() {  
  5.             public void run() {  
  6.                 for (int i = 0; i <= 100; i = i + 10) {  
  7.                     bar.setProgress(i);  
  8.                     try {  
  9.                         Thread.sleep(1000);  
  10.                     } catch (InterruptedException e) {  
  11.                         e.printStackTrace();  
  12.                     }}};  
  13.         }.start();  
  14.     }});  

 

 

这样的改变,或许能得到我们的需求,可以更新ProgressBar,但是如果你连续点击Start按钮,则会发现,进度条的变化凌乱了。因为这个操作是并发的,而界面只有一个,多次点击Button,则会多次创建多个线程,每个线程都会对界面进行改变,这样的操作是不安全的。所以Android规定,所有的UI更新操作必须放在UI线程中进行,即主线程中去执行。那么我们该怎么做才能让主线程同步操作来更新UI。

正确的做法:

Handler + Runnable

1)创建Runnable对象,UI更新操作主要在run()方法中。

2)创建Handler对象,调用handler.post(r),把r对象加入到线程队列中,然后线程队列就开始执行run()

3)run()中调用UI更新代码,如果是循环操作,可以用handler.postDelayed(r,1000).表示隔1秒后再把线程对象r加入到线程队列中,然后再去调用run().

注意:所有操作都在一个线程中,因为没有调用Thread的start()。

 

一般来说在工作线程中执行耗时任务,当任务完成时,会返回UI线程,一般是更新UI。这时有两种方法可以达到目的。一种是handler.sendMessage。发一个消息,再根据消息,执行相关任务代码。另一种是handler.post(r)。r是要执行的任务代码。意思就是说r的代码实际是在UI线程执行的。可以写更新UI的代码。(工作线程是不能更新UI的)

 

具体操作请看如下代码:

  方法一:handler.post(r);

Java代码  收藏代码
  1. public class MainActivity2 extends Activity {  
  2.   
  3.     ProgressBar bar = null;  
  4.     private Button btnStart = null;  
  5.     private Button btnEnd = null;  
  6.   
  7.     Handler handler = new Handler();  
  8.     //创建Runnable对象  
  9.     Runnable r = new Runnable() {  
  10.         int i = 0;// 用来更新bar  
  11.         @Override  
  12.         public void run() {  
  13.             System.out.println(Thread.currentThread().getId() + "-----run--->"  
  14.                     + Thread.currentThread().getName());  
  15.             i = i + 10;  
  16.             bar.setProgress(i);  
  17.             handler.postDelayed(r, 1000);  
  18.         }  
  19.     };  
  20.   
  21.     @Override  
  22.     protected void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_main);  
  25.         bar = (ProgressBar) findViewById(R.id.progressBar1);  
  26.         btnStart = (Button) findViewById(R.id.start);  
  27.         btnEnd = (Button) findViewById(R.id.stop);  
  28.         btnStart.setOnClickListener(new View.OnClickListener() {  
  29.             @Override  
  30.             public void onClick(View v) {  
  31.                 System.out.println(Thread.currentThread().getId()  
  32.                         + "-----Main--->" + Thread.currentThread().getName());  
  33.                 // 把r加入到线程队列,然后线程队列里就开始执行runnable对象中的run()  
  34.                 handler.post(r);  
  35.             };  
  36.         });  
  37.         btnEnd.setOnClickListener(new View.OnClickListener() {  
  38.             public void onClick(View v) {  
  39.                 handler.removeCallbacks(r);  
  40.             }  
  41.         });  
  42.     }  
  43. }  

 方法2:handler.sendMessage();

 

Java代码  收藏代码
  1. Handler handler = new Handler() {  
  2.         public void handleMessage(Message msg) {  
  3.             switch (msg.what) {  
  4.             case 0x333:  
  5.                 bar.setProgress(msg.arg1);  
  6.                 postDelayed(r, 1000);  
  7.                 break;  
  8.             }  
  9.         };  
  10.     };  
  11.   
  12.     Runnable r = new Runnable() {  
  13.         int i = 10;  
  14.         @Override  
  15.         public void run() {  
  16.             System.out.println(Thread.currentThread().getId() + "<>"  
  17.                     + Thread.currentThread().getName());  
  18.             Message msg = new Message();  
  19.             msg.what = 0x333;  
  20.             i = i + 10;  
  21.             msg.arg1 = i;  
  22.             handler.sendMessage(msg);  
  23.         };  
  24.     };  
  25.   
  26. start.setOnClickListener(new View.OnClickListener() {  
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 handler.post(r);  
  30.             }  
  31.         });  
0 0
原创粉丝点击