搜索
热搜: 活动 交友 discuz
查看: 4798|回复: 0
打印 上一主题 下一主题

子线程操作UI的几种方法

[复制链接]

160

主题

165

帖子

814

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
814
跳转到指定楼层
楼主
发表于 2018-3-11 15:39:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法1  Activity.runOnUiThread

方法如下:

  1. runOnUiThread(new Runnable() {
  2.     @Override
  3.     public void run() {
  4.       tv.setText("Hello");
  5.     }
  6. });
复制代码
runOnUiThread的源码

  1. public final void runOnUiThread(Runnable action) {  
  2.     if (Thread.currentThread() != mUiThread) {  
  3.         mHandler.post(action);  
  4.     } else {  
  5.         action.run();  
  6.     }  
  7. }  
复制代码
从源码中可以看出,如果当前线程是UI线程,那么行动是立即执行Runnable的run()。否则就是通过主线程的handler.post()方法将Runnable对象加入到消息队列中。


方法2  Handler





主线程中定义Handler如下:
  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更新,代码如下:

  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

  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中的内容,同样下面的代码也可以达到这种效果。

  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方法的源代码:

  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。


方法4 广播

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

方法5  使用AsyncTask


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



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



http://blog.csdn.net/seu_calvin/article/details/52120389



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|安卓论坛  

GMT+8, 2024-5-4 07:35 , Processed in 0.053003 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Design S!|ƽ̶

快速回复 返回顶部 返回列表