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

在看方法之前看一下Android中消息机制:

引用

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

不熟悉的朋友可以参考一下这篇文档:

Android知识梳理:消息机制之Handler:http://gqdy365.iteye.com/blog/2148925

Android知识梳理:消息机制之Looper :http://gqdy365.iteye.com/blog/2137494

下面基于上述原理说一下更新方法:

方法一:用Handler

1、主线程中定义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. //完成主界面更新,拿到数据
  8. String data = (String)msg.obj;
  9. updateWeather();
  10. textView.setText(data);
  11. break;
  12. default:
  13. break;
  14. }
  15. }
  16. };

2、子线程发消息,通知Handler完成UI更新:

  1. private void updateWeather() {
  2. new Thread(new Runnable(){
  3. @Override
  4. public void run() {
  5. //耗时操作,完成之后发送消息给Handler,完成UI更新;
  6. mHandler.sendEmptyMessage(0);
  7. //需要数据传递,用下面方法;
  8. Message msg =new Message();
  9. msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等;
  10. mHandler.sendMessage(msg);
  11. }
  12. }).start();
  13. }

方法一的Handler对象必须定义在主线程中,如果是多个类直接互相调用,就不是很方便,需要传递content对象或通过接口调用;

方法二:用Activity对象的runOnUiThread方法更新

在子线程中通过runOnUiThread()方法更新UI:

  1. new Thread() {
  2. public void run() {
  3. //这儿是耗时操作,完成之后更新UI;
  4. runOnUiThread(new Runnable(){
  5. @Override
  6. public void run() {
  7. //更新UI
  8. imageView.setImageBitmap(bitmap);
  9. }
  10. });
  11. }
  12. }.start();

如果在非上下文类中(Activity),可以通过传递上下文实现调用;

  1. Activity activity = (Activity) imageView.getContext();
  2. activity.runOnUiThread(new Runnable() {
  3. @Override
  4. public void run() {
  5. imageView.setImageBitmap(bitmap);
  6. }
  7. });

这种方法使用比较灵活,但如果Thread定义在其他地方,需要传递Activity对象;

方法三:View.post(Runnable r)

    1. imageView.post(new Runnable(){
    2. @Override
    3. public void run() {
    4. imageView.setImageBitmap(bitmap);
    5. }
    6. });

最新文章

  1. C# GUID转换成16位字符串或19位数字并确保唯一
  2. Leetcode Unique Paths II
  3. EF执行SQL
  4. js解决IE不支持数组的indexOf()方法
  5. JDBC数据类型
  6. CentOS7安装docker出错(Transaction check error)
  7. Spring 4.3.2+quartz2.2.3单机、集群+websocket集群实现文本或图片推送、接收及显示
  8. thinkphp用phpexcel读取excel,并修改列中的值,再导出excel,带往excel里写入图片
  9. windows内存映射学习及帮助类实现
  10. delphi : 取得网页源码内容
  11. 【百度地图API】如何根据摩卡托坐标进行POI查询,和计算两点距离
  12. Text Justification 实现两端对齐功能
  13. 关于CSS中的定位使用子绝父相(子类绝对位置和父类相对位置)
  14. 删除DataTable的指定行(Lambda)
  15. Django 路由报错友好提示
  16. iOS 拨打电话三种方式
  17. 董事局主席董事长总裁首席执行官CEO总裁董事监事区别
  18. 实验1 C语言开发环境使用和数据类型、运算符、表达式
  19. #leetcode刷题之路42-接雨水
  20. Catlike学习笔记(1.2)-使用Unity画函数图像

热门文章

  1. 搭建coreseek(sphinx+mmseg3)详细安装配置+php之sphinx扩展安装+php调用示例(转)
  2. HTML5 学习笔记 表单属性
  3. Python3内置字符串方法详解
  4. mysql数据类型与运算符
  5. Objective-C中的基本数据类型
  6. sql查看所有表大小的方法
  7. [k8s]helm原理&私有库搭建&monocularui和kubeapp探究
  8. CA证书的办理
  9. Ownerdrawn ComboBox
  10. python 快速获取文件类型