Android控件系列之ProgressBar&在Android中利用Handler处理多线程(★推荐)
2014-04-23 14:14
537 查看
文章来源:/article/5298154.html
学习目的:
1、掌握在Android中如何建立ProgressBar
2、掌握ProgressBar的常用属性
3、掌握在另一个线程中控制UI线程中的控件
介绍:
进度条是一种代表程序运行状态的动态控件,一般它不受用户控制,它的目的是为了告诉用户:请您稍等!
进度条分为2种:
第一种是不能告诉用户具体进度,但能一直处于滚动状态,适合未知结束时间的场合。
第二种时能告诉用户具体进度的,到达100%时,需要处理完所有后台任务。
您需要明白一下几点:
1、进度条只是反应进度的控件,真正的后台处理应该在另一个线程中进行。
2、反应实际进度的进度条的设计需要尽可能准确和平稳。
3、当进度条到达100%时,任务必须完成,否则用户会认为他们受到了欺骗。
样例实现了2种进度条,您会掌握如何在另一个线程中控制它,通常下载大量数据又不希望界面假死的情况下,您务必这么做:
第一个不停旋转的圆形进度条只适合不清楚结束时间,或者您能保证立刻会完成的操作。
第二个进度条拥有主进度和副进度,您可以根据实际需要分别为它们赋值,右边的TextView为了告诉用户实际进度的值,否则99%和100%将很难察觉出区别。
下方的按钮用来给您验证我们的确是可以一边异步下载数据一边使用界面上的其他控件的。
XML布局:
后台代码:
Handler
Android的控件是非线程安全的,在其他线程中操作主线程的控件将可能发生意外的情况,因此设计者希望对控件的操作依然交给主线程去完成,但在其他线程中,我们希望有一种机制去通知主线程去改变控件,于是Handler诞生了。这有点类似C#中的委托,但因为Java中的函数本身不能作为其他函数的参数,我们只能通过发送某个消息来告知主线程中的这个函数:你该如何操作某个控件了!
Handler对象也是运行一个线程上的,默认的空构造函数的Handler将会运行在创建它的线程上。也就是说,样例代码中的Handler是运行在主线程上的一个对象,它拥有一个接受消息的回调函数,这里可以处理一些逻辑,因为它是运行在主线程上的,所以它可以安全的操作控件。而在另一个线程中,我们可以截获Handler的Message,它就向一个邮递员,我们把要送达的信塞给他,然后告诉他:你快送过去吧!而信里则是你希望收信者做的事,邮递员根本没必要知道具体的任务。最终邮递员将信送达,主线程上的收信者拆开信封,看到“50”,他立刻明白:发信者要我把进度改成50%。
如果文字太过枯燥,看一下生动的图片吧:
总结:
本文详细介绍了在Android中使用ProgressBar的方法,并详细描述了在其他线程中如何操作UI线程的控件,这是Android开发必须掌握的知识,最后又分析了Handler的内部运行原理。
学习目的:
1、掌握在Android中如何建立ProgressBar
2、掌握ProgressBar的常用属性
3、掌握在另一个线程中控制UI线程中的控件
介绍:
进度条是一种代表程序运行状态的动态控件,一般它不受用户控制,它的目的是为了告诉用户:请您稍等!
进度条分为2种:
第一种是不能告诉用户具体进度,但能一直处于滚动状态,适合未知结束时间的场合。
第二种时能告诉用户具体进度的,到达100%时,需要处理完所有后台任务。
您需要明白一下几点:
1、进度条只是反应进度的控件,真正的后台处理应该在另一个线程中进行。
2、反应实际进度的进度条的设计需要尽可能准确和平稳。
3、当进度条到达100%时,任务必须完成,否则用户会认为他们受到了欺骗。
样例实现了2种进度条,您会掌握如何在另一个线程中控制它,通常下载大量数据又不希望界面假死的情况下,您务必这么做:
第一个不停旋转的圆形进度条只适合不清楚结束时间,或者您能保证立刻会完成的操作。
第二个进度条拥有主进度和副进度,您可以根据实际需要分别为它们赋值,右边的TextView为了告诉用户实际进度的值,否则99%和100%将很难察觉出区别。
下方的按钮用来给您验证我们的确是可以一边异步下载数据一边使用界面上的其他控件的。
XML布局:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <ProgressBar 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 ></ProgressBar> 11 12 <LinearLayout 13 android:orientation="horizontal" 14 android:layout_width="fill_parent" 15 android:layout_height="wrap_content" 16 > 17 <ProgressBar 18 style="?android:attr/progressBarStyleHorizontal" 19 android:id = "@+id/pb" 20 android:layout_width="170px" 21 android:layout_height="wrap_content" 22 ></ProgressBar> 23 <TextView 24 android:id="@+id/tvPersent" 25 android:paddingLeft="10px" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 > 29 </TextView> 30 </LinearLayout> 31 <Button 32 android:text="点我测试界面是否假死" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 ></Button> 36 </LinearLayout>
后台代码:
1 //进度条 2 ProgressBar pb = null; 3 //显示具体进度值的文本控件 4 TextView tvPersent = null; 5 /** Called when the activity is first created. */ 6 @Override 7 public void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.main); 10 11 pb = (ProgressBar)this.findViewById(R.id.pb); 12 tvPersent = (TextView)this.findViewById(R.id.tvPersent); 13 14 //申明一个线程,它将循环的更新某个值,这个值最终将被通过作为Message的一个参数发送给主线程的Handler 15 Thread thread = new Thread(myRun); 16 //开始异步执行 17 thread.start(); 18 } 19 20 //运行在主线程的Handler,它将监听所有的消息(Message) 21 Handler handler = new Handler(new Callback() { 22 23 @Override 24 public boolean handleMessage(Message arg0) { 25 //接受到另一个线程的Message,拿到它的参数,这个参数代表了进度 26 // TODO Auto-generated method stub 27 pb.setProgress(arg0.arg1); 28 tvPersent.setText(arg0.arg1 + "%"); 29 pb.setSecondaryProgress(arg0.arg1 + 10); 30 return false; 31 } 32 }); 33 34 //一个异步线程 35 Runnable myRun = new Runnable() { 36 int progressValue = 0; 37 @Override 38 public void run() { 39 while(true){ 40 // TODO Auto-generated method stub 41 //拿到主线程Handler的Message 42 Message msg = handler.obtainMessage(); 43 //将进度值作为消息的参数包装进去,进度自加1 44 msg.arg1 = progressValue ++; 45 //将消息发送给主线程的Handler 46 handler.sendMessage(msg); 47 //这个例子是反复循环,实际项目中可能没必要 48 if(progressValue>100){ 49 progressValue = 0; 50 } 51 try{ 52 //为了让您看到进度滚动效果,放慢进度上升的速度 53 Thread.sleep(300); 54 } 55 catch(InterruptedException e){ 56 e.printStackTrace(); 57 } 58 } 59 } 60 };
Handler
Android的控件是非线程安全的,在其他线程中操作主线程的控件将可能发生意外的情况,因此设计者希望对控件的操作依然交给主线程去完成,但在其他线程中,我们希望有一种机制去通知主线程去改变控件,于是Handler诞生了。这有点类似C#中的委托,但因为Java中的函数本身不能作为其他函数的参数,我们只能通过发送某个消息来告知主线程中的这个函数:你该如何操作某个控件了!
Handler对象也是运行一个线程上的,默认的空构造函数的Handler将会运行在创建它的线程上。也就是说,样例代码中的Handler是运行在主线程上的一个对象,它拥有一个接受消息的回调函数,这里可以处理一些逻辑,因为它是运行在主线程上的,所以它可以安全的操作控件。而在另一个线程中,我们可以截获Handler的Message,它就向一个邮递员,我们把要送达的信塞给他,然后告诉他:你快送过去吧!而信里则是你希望收信者做的事,邮递员根本没必要知道具体的任务。最终邮递员将信送达,主线程上的收信者拆开信封,看到“50”,他立刻明白:发信者要我把进度改成50%。
如果文字太过枯燥,看一下生动的图片吧:
总结:
本文详细介绍了在Android中使用ProgressBar的方法,并详细描述了在其他线程中如何操作UI线程的控件,这是Android开发必须掌握的知识,最后又分析了Handler的内部运行原理。
相关文章推荐
- Android控件系列之ProgressBar&在Android中利用Handler处理多线程
- Android多线程----异步消息处理机制之Handler详解
- 在android中利用多线程实现对控件的更新(动态修改文本框中的值)。简述原理并上传代码。
- Android 开发之多线程处理、Handler 详解
- Android 开发之多线程处理、Handler 详解
- Android控件系列之RadioButton&RadioGroup
- Android自定义控件系列 六:利用添加自定义布局来搞定触摸事件的分发,解决组合界面中特定控件响应特定方向的事件
- Android 开发之多线程处理、Handler 详解
- Android深入浅出系列之实例应用—程序运行进度提示条应用ProgressBar和Handler的使用
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- winform 利用 多线程 处理窗体假死,利用 Invoke BeginInvoke 处理子线程调用 UI 控件报错的问题
- Android控件系列之RadioButton&RadioGroup
- Android控件系列之相册Gallery&Adapter适配器入门&控件缩放动画
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- Android控件系列之RadioButton&RadioGroup
- Android 开发之多线程处理、Handler 详解
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- Android控件系列之RadioButton&RadioGroup
- <Android> 利用RelativeLayout实现中间控件长度自适应
- Android控件系列之RadioButton&RadioGroup