在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. });

主线程不能执行耗时的操作,子线程不能更新Ui的更多相关文章

  1. 关于Handler的理解,子线程不能更新UI的纠正和回调的思考

    开发Android这么久了,总会听到有人说:主线程不能访问网络,子线程不能更新UI.Android的主线程的确不能长时间阻塞,但是子线程为什么不能更新UI呢?今天把这些东西整理,顺便在子线程更新UI. ...

  2. Android多线程之(一)View.post()源码分析——在子线程中更新UI

    提起View.post(),相信不少童鞋一点都不陌生,它用得最多的有两个功能,使用简便而且实用: 1)在子线程中更新UI.从子线程中切换到主线程更新UI,不需要额外new一个Handler实例来实现. ...

  3. android 不能在子线程中更新ui的讨论和分析

    问题描写叙述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是仅仅能在主线程中更改 ui.子线程要 ...

  4. 如何在子线程中更新UI

    一:报错情况 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that creat ...

  5. Android在子线程中更新UI(二)

    MainActivity如下: package cc.testui2; import android.os.Bundle; import android.view.View; import andro ...

  6. 使用Handler在子线程中更新UI

    Android规定仅仅能在主线程中更新UI.假设在子线程中更新UI 的话会提演示样例如以下错误:Only the original thread that created a view hierach ...

  7. Android在子线程中更新UI(一)

    MainActivity如下: package cc.testui1; import android.os.Bundle; import android.os.Handler; import andr ...

  8. Android开发UI之在子线程中更新UI

    转自第一行代码-Android Android是不允许在子线程中进行UI操作的.在子线程中去执行耗时操作,然后根据任务的执行结果来更新相应的UI控件,需要用到Android提供的异步消息处理机制. 代 ...

  9. Android子线程中更新UI的4种方法

    方法一:用Handler 1.主线程中定义Handler: Handler mHandler = new Handler() { @Override public void handleMessage ...

随机推荐

  1. 微信公众平台消息接口PHP版

    使用前提条件:拥有一个公网上的HTTP服务器主机空间,具有创建目录.上传文件等权限.推荐新浪的SAE.http://sae.sina.com.cn/ 首先请注册微信公众平台的账号,注册地址:http: ...

  2. ItelliJ基于Gradle创建及发布Web项目(二)

    上一篇介绍了IteliJ创建WEB项目的过程,这一篇介绍一下和本地WEB服务器(以Tomcat为例)的关联方法和发布流程. WEB服务器的关联 1. 点击IDE右上角的一个带有三角形标识的按钮,如下图 ...

  3. RFID UHF(EPC)标签使用常识

    文章复制来的,原作者原文点击这里 现在做UHF应用的越来越多了,如何根据实际应用设计系统以达到更佳的使用效果,其中对UHF标签相关内容的了解至关重要,很多朋友对标签的了解不多,在此不才,整理了一些资料 ...

  4. FPGA管脚分配文件保存方法

    使用别人的工程时,有时找不到他的管脚文件,但可以把他已经绑定好的管脚保存下来,输出到文件里. 方法一: 查看引脚绑定情况,quartus -> assignment -> Pins,打开F ...

  5. 从JSON数据中取出相关数据

    参考: http://www.cnblogs.com/shuilangyizu/p/6019561.html JSON数据如下: { "total": 1, "rows& ...

  6. IronPython使用

    C#: class Program { static void Main(string[] args) { ScriptEngine engine = Python.CreateEngine(); S ...

  7. 模板中的 TemplateBinding 问题

    昨天一个朋友向我求助一个自定义水印控件绑定的问题,问题出在文本框中输入的文本,不能绑定到 相应的依赖属性上(自定义的依赖属性 PassText),他纠结了很久找不出问题所在.问题帮他解决后,这里稍 做 ...

  8. 三、请求库之requests模块

    一 介绍   #介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3) #注意:requests库发送请求将网 ...

  9. pip install read time-out

    Problem ReadTimeoutError: HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out. 1 S ...

  10. msf提权命令/meterpreter下的几个命令

    废话: 今天本来日学校内网.以为是台08.结果稀里糊涂居然日了宿舍哥们儿的PC机.按道理都该装杀毒的才对,我舍友都不装的.裸装上阵说的就是我舍友了.劝各位大佬.把杀毒装好.补丁打好. 通过这次我也学到 ...