Handler消息传递机制
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消息传递机制相关推荐
- 【Android开发】线程与消息处理-Handler消息传递机制之Looper
在前面已经介绍了在Android中如何创建.开启.休眠和中断线程.不过,此时并没有在新创建的子线程中对UI界面上的内容进行操作,如果应用前面介绍的方法对UI界面进行操作,将抛出异常. 为此,Andro ...
- Android Handler消息传递机制
Android中只允许UI线程(也就是主线程)修改Activity里的UI组件.实际开发中,新启动的线程需要周期性地改变界面组件的属性值就需要借助Handler的消息传递机制. Handler类 Ha ...
- android handler 传递对象,Android之Handler消息传递机制详解
前言 在Android开发中,多线程应用是非常频繁的,其中Handler机制随处可见. 下面就本人对Handle的一些理解与大家一起分享,共同回顾下Handle异步消息传递机制. 1.Handler是 ...
- Android中Handler消息传递机制应用之子线程不允许操作主线程的组件
场景 进程 一个Android应用就是一个一个进程,每个应用在各自的进程中运行. 线程 比进程更小的独立运行的基本单位,一个进程可以包含多个线程. 要求 一个TextView和一个Button,点击B ...
- Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理
Loop,Message,MessageQueue概念理解: Message:Handler发送.接收和处理的消息对象 Looper:每个线程只能拥有一个Looper.它的looper()方法负责循环 ...
- Handler消息传递机制(一)
为什么要用Handler: 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的原 ...
- Android中的消息机制:Handler消息传递机制
参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...
- Handler 消息传递机制
1,Handler 的概念 Handler 是用来干什么的? 1)执行计划任务,可以在预定的时间执行某些任务,可以模拟定时器 2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创 ...
- Android开发:图文分析 Handler通信机制 的工作原理
前言 在Android开发的多线程应用场景中,Handler机制十分常用 下面,将图文详解 Handler机制 的工作原理 目录 1. 定义 一套 Android 消息传递机制 2. 作用 在多线程的 ...
最新文章
- windows平台下 c++获取 系统版本 网卡 内存 CPU 硬盘 显卡信息
- from torch._C import * ImportError: DLL load failed 动态链接库(DLL)初始化例程失败
- 安卓 无权限 访问_U盘提示无权限访问怎么办 电脑U盘访问权限管理
- ABAP function module 的使用
- 新研究表明 深层神经网络的功能存在局限性
- python在windows平台的多版本配置
- 使用电脑adb给Essential Phone刷机 —(官方篇)
- win10 mysql 主从复制_win10 使用Docker配置mysql主从复制
- k8s高可用集群_搭建高可用集群(部署master2和node节点)---K8S_Google工作笔记0058
- 二叉搜索树相关性质的应用
- H53D旋转-遁地龙卷风
- 神经网络模型结果怎么看,神经网络模型怎么预测
- 新浪微博用户兴趣建模系统架构
- 计算机毕业设计Java影片租赁系统(系统+程序+mysql数据库+Lw文档)
- 2023你冲不冲,冲冲冲冲~~
- 如何将两个路由器连接在一起
- 【产品】产品原型设计工具 Axure 和 Mockplus 对比
- PTA 1054 求平均值 (20 分)
- ATFX:5年期LPR利率大降15基点,USDCNH涨破年内高点
- Pygame实战:升级后的2048小游戏—解锁新花样,根本停不下来【附源码】
热门文章
- Seaborn使用regplot函数可视化散点图并添加回归曲线以及回归线对应的置信区间(Scatter plot with regression line)
- R语言ggplot2条形图(bar plot)可视化:更改一个条形(bar)的颜色、突出一个条形(bar)的颜色
- Python使用numpy中trim_zeros函数去除首尾0值的语法
- pyinstaller打包生成的exe文件并使用python终止后台的exe程序运行
- R语言ggplot2可视化百分比显示实战:纵轴显示为百分比、在柱状图上显示百分比、按照因子变量绘制分组子图(纵轴显示为百分比)、可视化图中显示数据百分比
- R语言生存分析COX回归分析实战:以乳腺癌数据为例
- R构建列联表(Contingency Table or crosstabs)
- 什么是BI?什么是DW?ETL(Extract-Transform-Load)是什么?
- 影像组学视频学习笔记(32)-使用SimpleITK进行N4偏置场校正、Li‘s have a solution and plan.
- access的未来发展 ieee_传感器行业发展路在何方 多国专家齐聚来一场头脑风暴