Android中的Handler机制

直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,如下错 误:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.翻译过来就是:只有创建这个控件的线程才能去更新该控件的内容。;所有的UI线程要去负责View的创建并且维护它,例如更新某个TextView的显示,都必须在主线程中去做,我们不能直接在UI线程中去创建子线程,要利用消息机制:handler;android给我们提供了Handler机制来解决这样的问题:如下就是handler的简单工作原理图:

<img src="https://img-blog.csdn.net/20150418223147384?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWdvbmllMjAxMjE4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

在android中一个线程对应一个Looper对象,而一个Looper对象又对应一个MessageQueue(消息队列)。MessageQueue用于存放Message(消息),在MessageQueue中,存放的消息按照FIFO(先进先出)原则执行,MessageQueue被封装在Looper中。 Looper对象用来为一个线程开启一个消息循环,从而操作MessageQueue。默认情况下,Android中新创建的线程是没有开启消息循环的,但主线程除外。系统会自动为主线程创建Looper对象,开启消息循环。所以,当在主线程中的应该下面的代码创建Handler对象是不会出错,而如果在新创建的非主线程中的应用下面的代码创建Handler对象,将产生异常信息。 Handler handler=new handler();//为主线程创建Handle  如果想要在非线程中创建Handler对象,首先需要使用Looper类的prepare方法来初始化一个Looper对象,然后在创建一个Handler对象,在使用Looper类的loop()方法启动Looper,从消息队列中获取和处理消息。

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;public class LooperThread extends Thread {public Handler handler1;  //声明一个Handler对象@Overridepublic void run() {super.run();Looper.prepare();   //初始化Looper对象// 实例化一个Handler对象 handler1 = new Handler() {public void handleMessage(Message msg) {Log.i("Looper",String.valueOf(msg.what));} };Message m=handler1.obtainMessage();   //获取一个消息m.what=0x11;   //设置Message的what属性的值handler1.sendMessage(m);    //发送消息Looper.loop();    //启动Looper}
}

(1) Looper类用来为一个线程开启一个消息循环。

默认情况下android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) 
    Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。

(2) 通常是通过Handler对象来与Looper进行交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。 
    默认情况下Handler会与其被定义时所在线程的Looper绑定,比如,Handler在主线程中定义,那么它是与主线程的Looper绑定。 
mainHandler = new Handler() 等价于new Handler(Looper.myLooper()). 
Looper.myLooper():获取当前进程的looper对象,类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。

(3) 在非主线程中直接new Handler() 会报如下的错误: 
E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception 
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。

(4) Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。

注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

(5) 基于以上知识,可实现主线程给子线程(非主线程)发送消息。

把下面例子中的mHandler声明成类成员,在主线程通过mHandler发送消息即可。

Handler消息传递机制相关推荐

  1. 【Android开发】线程与消息处理-Handler消息传递机制之Looper

    在前面已经介绍了在Android中如何创建.开启.休眠和中断线程.不过,此时并没有在新创建的子线程中对UI界面上的内容进行操作,如果应用前面介绍的方法对UI界面进行操作,将抛出异常. 为此,Andro ...

  2. Android Handler消息传递机制

    Android中只允许UI线程(也就是主线程)修改Activity里的UI组件.实际开发中,新启动的线程需要周期性地改变界面组件的属性值就需要借助Handler的消息传递机制. Handler类 Ha ...

  3. android handler 传递对象,Android之Handler消息传递机制详解

    前言 在Android开发中,多线程应用是非常频繁的,其中Handler机制随处可见. 下面就本人对Handle的一些理解与大家一起分享,共同回顾下Handle异步消息传递机制. 1.Handler是 ...

  4. Android中Handler消息传递机制应用之子线程不允许操作主线程的组件

    场景 进程 一个Android应用就是一个一个进程,每个应用在各自的进程中运行. 线程 比进程更小的独立运行的基本单位,一个进程可以包含多个线程. 要求 一个TextView和一个Button,点击B ...

  5. Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理

    Loop,Message,MessageQueue概念理解: Message:Handler发送.接收和处理的消息对象 Looper:每个线程只能拥有一个Looper.它的looper()方法负责循环 ...

  6. Handler消息传递机制(一)

    为什么要用Handler: 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的原 ...

  7. Android中的消息机制:Handler消息传递机制

    参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...

  8. Handler 消息传递机制

    1,Handler 的概念 Handler 是用来干什么的? 1)执行计划任务,可以在预定的时间执行某些任务,可以模拟定时器 2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创 ...

  9. Android开发:图文分析 Handler通信机制 的工作原理

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 下面,将图文详解 Handler机制 的工作原理 目录 1. 定义 一套 Android 消息传递机制 2. 作用 在多线程的 ...

最新文章

  1. windows平台下 c++获取 系统版本 网卡 内存 CPU 硬盘 显卡信息
  2. from torch._C import * ImportError: DLL load failed 动态链接库(DLL)初始化例程失败
  3. 安卓 无权限 访问_U盘提示无权限访问怎么办 电脑U盘访问权限管理
  4. ABAP function module 的使用
  5. 新研究表明 深层神经网络的功能存在局限性
  6. python在windows平台的多版本配置
  7. 使用电脑adb给Essential Phone刷机 —(官方篇)
  8. win10 mysql 主从复制_win10 使用Docker配置mysql主从复制
  9. k8s高可用集群_搭建高可用集群(部署master2和node节点)---K8S_Google工作笔记0058
  10. 二叉搜索树相关性质的应用
  11. H53D旋转-遁地龙卷风
  12. 神经网络模型结果怎么看,神经网络模型怎么预测
  13. 新浪微博用户兴趣建模系统架构
  14. 计算机毕业设计Java影片租赁系统(系统+程序+mysql数据库+Lw文档)
  15. 2023你冲不冲,冲冲冲冲~~
  16. 如何将两个路由器连接在一起
  17. 【产品】产品原型设计工具 Axure 和 Mockplus 对比
  18. PTA 1054 求平均值 (20 分)
  19. ATFX:5年期LPR利率大降15基点,USDCNH涨破年内高点
  20. Pygame实战:升级后的2048小游戏—解锁新花样,根本停不下来【附源码】

热门文章

  1. Seaborn使用regplot函数可视化散点图并添加回归曲线以及回归线对应的置信区间(Scatter plot with regression line)
  2. R语言ggplot2条形图(bar plot)可视化:更改一个条形(bar)的颜色、突出一个条形(bar)的颜色
  3. Python使用numpy中trim_zeros函数去除首尾0值的语法
  4. pyinstaller打包生成的exe文件并使用python终止后台的exe程序运行
  5. R语言ggplot2可视化百分比显示实战:纵轴显示为百分比、在柱状图上显示百分比、按照因子变量绘制分组子图(纵轴显示为百分比)、可视化图中显示数据百分比
  6. R语言生存分析COX回归分析实战:以乳腺癌数据为例
  7. R构建列联表(Contingency Table or crosstabs)
  8. 什么是BI?什么是DW?ETL(Extract-Transform-Load)是什么?
  9. 影像组学视频学习笔记(32)-使用SimpleITK进行N4偏置场校正、Li‘s have a solution and plan.
  10. access的未来发展 ieee_传感器行业发展路在何方 多国专家齐聚来一场头脑风暴