Android开发子线程操作UI的几种方法

 

Android开发----子线程操作UI的几种方法

  8161人阅读  评论(0)  收藏  举报
  分类:

在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法:

在看方法之前需要了解一下Android中的消息机制


方法1  Activity.runOnUiThread

方法如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. runOnUiThread(new Runnable() {  
  2.     @Override  
  3.     public void run() {  
  4.       tv.setText("Hello");  
  5.     }  
  6. });  
这种方法简单易用,如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,就发布到事件队列的UI线程。其实和Handler差不多,都是将这个更新UI的请求消息,加入到事件队列,等待主线程空闲的时候执行。


方法2  Handler

主线程中定义Handler如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Handler mHandler = new Handler() {    
  2.         @Override    
  3.         public void handleMessage(Message msg) {    
  4.             super.handleMessage(msg);    
  5.             switch (msg.what) {    
  6.             case 0:    
  7.                 String data = (String)msg.obj;    
  8.                 textView.setText(data);    
  9.                 break;    
  10.             default:    
  11.                 break;    
  12.             }    
  13.         }    
  14.     };  

子线程发消息,通知Handler完成UI更新,代码如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. new Thread(new Runnable(){    
  2.             @Override    
  3.             public void run() {    
  4.                 //耗时操作                  
  5.                 mHandler.sendEmptyMessage(0);    
  6.                 Message msg =new Message();    
  7.                 msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等   
  8.                 mHandler.sendMessage(msg);    
  9.             }    
  10.         }).start();    

方法3  View.post

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. final Button btn =(Button)findViewById(R.id.btn);  
  2. btn.post(new Runnable(){  
  3. @Override  
  4.     publicvoid run() {  
  5.     btn.setText("Hello");  
  6.     }  
  7.   });   

上面的代码就是更新btn中的内容,同样下面的代码也可以达到这种效果。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Handler handler = new Handler();  
  2. final Button btn = (Button)findViewById(R.id.btn);  
  3. handler.post(new Runnable(){  
  4.     @Override  
  5.     public void run() {  
  6.     btn.setText("Hello");  
  7.   }  
  8. });   

这个是用handler.post方法,一个是用View.post方法,handler.post方法已经在Android的消息机制中介绍过了,其实最终也是调用了方法2中的send方法。

现在看一下View.post方法的源代码:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public boolean post(Runnable action) {  
  2. Handler handler;  
  3. AttachInfo attachInfo = mAttachInfo;  
  4. if (attachInfo != null) {  
  5.     handler = attachInfo.mHandler;  
  6. else {  
  7.     // Assume that post will succeed later  
  8.     ViewRootImpl.getRunQueue().post(action);  
  9.     return true;  
  10. }  
  11.     return handler.post(action);  
  12. }  

方法中主要的功能代码就是attachInfo.mHandler,获取当前线程(即UI线程)的Hanlder然后将action对象post到Handler里。在Handler里的处理过程上面链接文已经分析的很清楚了,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler的dispatchMessage方法里,第一句话就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。


方法广播

子线程中发送广播,主线程中接收广播并更新UI。


方法5  使用AsyncTask

为了简化子线程中访问UI,系统提供给了我们AsyncTask。

AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行进度和结果传递给主线程并更新UI。本质上来说AsyncTask封装了ThreadHandler,但是AsyncTask不适合进行特别耗时的后台任务,如果需要进行特别耗时的任务,建议使用线程池。

不同API版本的AsyncTask具有不同的表现,因此需要注意。为了控制篇幅,具体的AsyncTask的使用方法和工作原理,写在这篇文章,AsyncTask的使用以及源码解析,有兴趣的同学可以查看。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值