Android Handler机制

1.什么是Handler?

  Handler是可以通过发送和处理Message和Runnable对象来关联相应线程的MessageQueue。通常我们认为它是一种异步机制。

  a.可以让对应的Message和Runnable在未来的某个时间点进行相应的处理。

  b.让自己想要的耗时操作在子线程中完成,让更新UI的操作在主线程中完成,而子线程与主线程之间的通信就是靠Handler来完成。

2.Handler内部的实现机制

  面试的时候,Handler的原理问到的概率还是蛮大的,不光只是为了面试,我们好好去了解一下Handler的原理,那么对于我们去使用Handler而言是非常有好处的,至少我们知道我们发送的消息如何发送到了UI线程的,当出现问题时,我们只要小小一分析便会知道问题发生于何处,然后解决它,好了,闲话不多扯了,下面来介绍Handler机制的实现原理。
  Handler机制也可叫异步消息机制,它主要由4个部分组成:Message,Handler,MessageQueue,Looper,在上面我们已经接触到了Message和Handler,接下来我们对4个成员进行着重的了解:

1.Message
  Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。使用Message的arg1和arg2便可携带int数据,使用obj便可携带Object类型数据。

2.Handler
  Handler顾名思义就是处理者的意思,它只要用于在子线程发送消息对象Message,在UI线程处理消息对象Message,在子线程调用sendMessage方法发送消息对象Message,而发送的消息经过一系列地辗转之后最终会被传递到Handler的handleMessage方法中,最终在handleMessage方法中消息对象Message被处理。

3.MessageQueue
  MessageQueue就是消息队列的意思,它只要用于存放所有通过Handler发送过来的消息。这部分消息会一直存放于消息队列当中,等待被处理。每个线程中只会有一个MessageQueue对象,请牢记这句话。其实从字面上就可以看出,MessageQueue底层数据结构是队列,而且这个队列只存放Message对象。

4.Looper
  Looper是每个线程中的MessageQueue的管家,调用Looper的loop()方法后,就会进入到一个无限循环当中,然后每当MesssageQueue中存在一条消息,Looper就会将这条消息取出,并将它传递到Handler的handleMessage()方法中。每个线程只有一个Looper对象。

  了解了上述Handler机制的4个成员后,我们再来把思路理一遍:首先在UI线程我们创建了一个Handler实例对象,无论是匿名内部类还是自定义类生成的Handler实例对象,我们都需要对handleMessage方法进行重写,在handleMessage方法中我们可以通过参数msg来写接受消息过后UIi线程的逻辑处理,接着我们创建子线程,在子线程中需要更新UI的时候,新建一个Message对象,并且将消息的数据记录在这个消息对象Message的内部,比如arg1,arg2,obj等,然后通过前面的Handler实例对象调用sendMessge方法把这个Message实例对象发送出去,之后这个消息会被存放于MessageQueue中等待被处理,此时MessageQueue的管家Looper正在不停的把MessageQueue存在的消息取出来,通过回调dispatchMessage方法将消息传递给Handler的handleMessage方法,最终前面提到的消息会被Looper从MessageQueue中取出来传递给handleMessage方法,最终得到处理。这就是Handler机制整个的工作流程

 

3.如何使用Handler让子线程与子线程之间进行通信?

  如今的面试,Handler基本上很多面试者都会流畅的说出来,但是如果想要给面试官亮点,那就需要我们对Handler了解的十分透彻,我们通常代码中是子线程与主线程进行异步通信,那么子线程与子线程之间也可以吗?当然可以,只不过我们需要对Looper足够了解,深入研究Hanlder你可以看笔者Handler源码分析部分。那么我们如果需要子线程A和子线程B之间进行Handler通信,而且是子线程A向子线程B发送消息,那么我们应该怎样做呢?

public class MainActivity extends AppCompatActivity {private Handler threadHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}class ThreadA extends Thread{@Overridepublic void run() {super.run();Looper.prepare();threadHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//收到来自于ThreadB的消息,注意这里运行在ThreadA线程中//......}};Looper.loop();}}class ThreadB extends Thread{@Overridepublic void run() {super.run();Looper looper = Looper.myLooper();Message message = new Message();message.obj = "ThreadB发送消息到ThreadA";//......threadHandler.sendMessage(message);}}}
  • 笔者写的这份代码也许不好,但是没有关系,我们只需要学会其中几个关键的地方,如何让ThreadB往ThreadA中发送消息,首先你得在ThreadA中准备一个Looper,也就是消息轮询大管家,然后准备发送消息的Handler,准备发送消息的Handler很容易理解,那就是在ThreadA中生成一个Handler对象即可,那么准备Looper怎么做呢?在ThreadA中调用Looper.prepare(),然后再调用Looper.loop()即可

 

关于handler更多:https://blog.csdn.net/qq_30107007/article/details/88662219

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/415144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你的鼠标有多快-小游戏

HTML <div class"box"><h3>你的鼠标有多快&#xff1f;</h3><p>游戏说明&#xff1a;点击开始游戏&#xff0c;随机掉下QQ表情&#xff0c;点中它&#xff0c;千万别让它掉下去&#xff01;&#xff01;</p><input type"butto…

input文件上传代码片段

需求&#xff1a;自己留个记录 <div class"button—2" click"uploadFile"><input type"file" ref"file" multiple"multiple" change"fileChange" style"display:none">上传</div>as…

android图片查看器,实现图片加载进度监听,实现保存图片

1、添加依赖 implementation com.github.bumptech.glide:glide:4.6.1 compile com.github.chrisbanes:PhotoView:2.0.0 compile com.squareup.okhttp3:okhttp:3.9.0 2、实现fragmentactivity&#xff1a; /*** 作者&#xff1a;created by meixi* 邮箱&#xff1a;131647168…

iPhone X Web 设计

iPhone X Web 设计 原文地址&#xff1a;https://webkit.org/blog/7929/designing-websites-for-iphone-x/ 开箱即用(开发者无需进行任何设置)&#xff0c;在iPhone X中&#xff0c;Safari 就可以完美的在全面屏上显示你既有的网站。网页内容会自动插入到显示的安全区域以至于不…

python 文件读取报错 ‘utf-8‘ codec can‘t decode

初学python遇到一个文件读取遇到问题 utf-8 codec cant decode byte 0xb0 in position 611我报错的写法 with open(filename,r) as f:LISTf.readlines()实际问题是我的电脑默认读取编码为utf-8,但是文件的编码为gbk,只要指定好编码为gbk就OK。 with open(filename,r,encodin…

Android 屏幕灭屏亮屏广播,屏幕灭屏亮屏监听,广播实现按键监听

service 类注册广播进行监听 /*** 作者&#xff1a;created by meixi* 邮箱&#xff1a;13164716840163.com* 日期&#xff1a;2018/9/27 09*/ public class Serview extends Service {/*** 广播接受者*/private BroadcastReceiver mBatInfoReceiver;private String TAG &quo…

python WindroseAxes 报错 has no attribute ‘Appender‘

引用代码 from windrose import WindroseAxes报错&#xff1a;module matplotlib.docstring has no attribute Appender 问题是我目前安装的python 3.8&#xff0c;windrose也要安装最新的。 安装方法 第一种&#xff1a; pip install githttps://github.com/python-windr…

[转载] 我的WafBypass之道(SQL注入篇)

我的WafBypass之道&#xff08;SQL注入篇&#xff09; Web安全 作者&#xff1a;先知技术社区 2016-11-23 7,566【本文转自安全脉搏战略合作伙伴先知技术社区 原帖地址 安全脉搏编辑huan9740整理发布】 0x00 前言 去年到现在就一直有人希望我出一篇关于waf绕过的文章&#xf…

Android 设置系统闹钟,日历写入。实现demo

实现方法1——代码闹钟 可变时间格式&#xff1a;"yyyy-MM-dd HH:mm:ss" 保存闹钟时间&#xff1a; SimpleDateFormat df new SimpleDateFormat("HH:mm");//设置日期格式 String thistime df.format(new Date()); SharedPreferences sharedPreferenc…

centos 安装 fortran

1、 yum install gcc-c2、 yum install gcc-gfortran

前端学习(2677):懂代码之表格BaseTable删除操作

1第一步 <el-table-column label"操作" width"180" align"center"><template slot-scope"scope"><el-buttontype"text"icon"el-icon-edit"click"handleEdit(scope.$index, scope.row)"&…

Linux之Ubuntu下安装屏幕录像软件(SimpleScreenRecorder)【摘抄】

本博文全文属于摘抄自&#xff1a; (见文末处参考文献)(由于担心原博文丢失&#xff0c;以后查找不到&#xff0c;故此原文摘抄&#xff0c;以备日后多次查阅) 在日常工作中&#xff0c;有时需要对屏幕进行录像&#xff0c;以制作讲解文档等。下面介绍在Linux上安装屏幕录像软件…

Android精准计步器

demo链接&#xff1a;https://download.csdn.net/download/meixi_android/10690974 工具类&#xff1a; public class StepDetector implements SensorEventListener {//存放三轴数据float[] oriValues new float[3];final int ValueNum 4;//用于存放计算阈值的波峰波谷差值…

docker 目录 挂载

docker容器启动的时候&#xff0c;如果要挂载宿主机的一个目录&#xff0c;可以用-v参数指定。 譬如我要启动一个centos容器&#xff0c;宿主机的/share目录挂载到容器的/share目录&#xff0c;可通过以下方式指定&#xff1a; docker run -it -v /share:/share centos /bin/…

工作177:表单重置项目处理

<template><!--新建账号对话框--><el-dialog title"新建账号" :visible.sync"dialogFormVisible" close"close"><el-form ref"form" :model"form" size"medium" :label-width"formLabe…

docker删除所有镜像和容器

需求&#xff1a;重新进行开发&#xff0c;需要清空目前的镜像和容器。 1、删除容器 1&#xff09;首先需要停止所有的容器 docker stop $(docker ps -a -q) 2&#xff09;删除所有的容器&#xff08;只删除单个时把后面的变量改为image id即可&#xff09; docker rm $(d…

Ubuntu配置完全教程

前言 最近将旧电脑换成了Ubuntu系统&#xff0c;在网上找了许多优化和配置教程&#xff0c;今天整理一份完整的教程给大家分享 系统清理 卸载LibreOffice libreoffice事ubuntu自带的开源office软件&#xff0c;体验效果不如windows上的office&#xff0c;于是选择用WPS来替代&a…

Android assets文件使用

1、在main文件夹下创建assets文件夹 2、assets文件夹下可创建image文件夹&#xff0c;text文件夹&#xff0c;image文件夹下存放jpg或png图片。text文件夹下存放.txt文本 3、读取assets文件内容&#xff1a; entity类&#xff1a; public class Book {private static final…