Android之handler消息处理机制详解

这篇具有很好参考价值的文章主要介绍了Android之handler消息处理机制详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

handler消息处理机制

handler是什么?

​ Handler是一个在消息处理机制中负责发送和处理消息的类,是消息处理的关键。

消息处理涉及的主要类

  • Handler:负责发送消息和处理消息
  • Looper:内置一个死循环,可以不断的取出消息并通知handler处理消息,是handler起作用的基础
  • Message:消息实体类
  • MessageQueue:消息队列,负责存储消息

消息处理的基本原理

handler消息机制,android,ui,java

Thread、Handler、Lopper、MessageQueue对应关系

​ 一个Lopper对应一个MessageQueue,因为Looper内置了一个消息队列。

​ 一个Thread只能有一个Lopper。

​ 一个Handler对象对应一个Thread和Thread的消息队列(但是一个Thread内可以有多个Handler)。当你创建一个Handler时,它就和Thread的消息队列绑定在一起。

特别注意:Handler虽然和Looper是一一对应的,但是Hanlder本身并不含有Looper,Looper是通过线程内部的存储类存储在Thread里的的,而Looper内置了一个消息队列。

消息传递基本思想

​ 在线程B中获取属于线程A的handler,在B中创建的message可以通过调用handler.sendmessage(message对象)将消息添加到A线程的消息队列中去,A线程的Looper循环会取出消息并通知hanlder去处理消息,调用回调函数handler.handleMessage(用户一般要重写此方法)去处理消息。所以就实现了把B线程的数据封装到message中传递给线程A,通过线程A中重写handler的handleMessage方法在线程A中处理消息。

handler消息处理机制能做什么?

  • 实现消息的异步处理,例如将子线程的数据通过Message传递到主线程中
  • 一般来说UI控件只能在主线程中更新,但是在子线程中可以通过handler更新UI

Handler

​ Handler用于发送、处理消息,Handler本身不含有message,而message中有个target属性(hanlder类型),用于此条标识消息要由哪个handler去处理。

​ Handler有多个构造函数,但本质上都是外部传入一个Looper,Handler属于哪个现场取决于传入Looper属于哪个线程。

post(runable)				//发送消息,Runnable是消息回调,经过消息循环引发消息回调函数执行;
    
sendMessage(message)		//发送消息,经过消息循环派发消息处理函数中处理消息;

dispatchMessage(messsage)   //派发消息,主要作用就是根据情况调用回调函数。
                     //若是post或带有回调函数则执行回调函数,否则执行消息处理函数Handler的handleMessage(通常派生类写)。

​ sendMessage和post两种发消息的本质是一样的,都是发送一个Message。只是post(runable r)方法发送的是一个callback属性为r的message,两个方法发出的消息在loop取出后,最终都会交到dispatchMessage处理。

handler消息处理的流程图

handler消息机制,android,ui,java

dispatchMessage(派发消息)源码分析

​ 从代码中可以看到message本身有一Runable接口,只有它为空则执行handlemessage。

​ hanlder本身包含一个回调函数handlemessage,它本身又包含一个callback接口,接口里面又是一个handkemessage回调函数,到底执行哪个handlemessage就在dispatchMessage中判断,判断优先级是:消息回调 > handler的callback的回调 > handler本身回调

    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {		//首先判断消息本身Runable是否为空,不为空就只执行消息的callback(Runable类型)
            handleCallback(msg);
        } else {
            if (mCallback != null) {	//如果handler的callback接口不为空,则执行hanlder的callback的回调函数
                if (mCallback.handleMessage(msg)) {	
                    return;				//再如果callback的回调函数中返true,则不执行hanlder本身的回调函数
                }
            }
            handleMessage(msg);			//当消息的callback为空且handler的callback也为空或者,才执行handler本身的回调函										数
        }
    }

Looper

​ 实现Thread的消息循环和消息派发,缺省情况下Thread是没有这个消息循环的,即没有Looper;

​ 需要主动去创建(调用Lopper.prepare()),然后启动消息循环(调用Lopper.loop());与外部的交互通过Handler进行;

  • Lopper.prepare() //为当前线程创建Lopper对象,实质上是new一个Looper然后通过当前线程内置的存储类ThreadLoacl保存该Looper,由于每个线程只能有一个Looper,所以通过prepare()创建Looper每次会判断当前线程是否有Looper,有则异常。handler消息机制,android,ui,java
  • Looper.loop() //通过死循环来不断取出当前线程Looper的消息队列中的消息,消息队列没有数据了就会挂起,核心代码如下图

handler消息机制,android,ui,java

  • Looper.myLooper()//获取当前线程的Looper对象,底层是通过当前线程内置的线程存储类ThreadLoacl.get()来获得,获得的内容在Looper执行prepare()时通过ThreadLoacl.set()传入的Looper对象。

handler消息机制,android,ui,java

handler消息机制,android,ui,java

  • Looper.myQueue()//获取Looper对应的消息队列
  • Looper.getMainLooper()//获取主线程的Looper对象

拓展 —ThreadLocal

​ ThreadLoacal是Thread中内置的存储类,其本身并不存储数据,而是通过它内置的ThreadLoacaMap来存储数据的。

其主要方法有:

  • set(T t) //设置线程变量
  • get() //获得线程变量,调用前一定要调用set方法否则报空指针异常

在不同线程中执行get方法得到的值是不同的,得到的值是在对应线程set的值

Message

public final class Message implements Parcelable {
    //标识消息
    public int what;
    int flags;
    long when;
    //传递简单数据
      public int arg1;
    public int arg2;
    //传递较复杂数据 对象
    public Object obj;
    Bundle data;
    //处理消息的目标Handler
    Handler target;   
    //消息派发时 执行的Runnable对象
    Runnable callback;  
    //使消息形成链表
    Message next;
    //建立一个消息pool,回收msg,以避免重复创建节约开销
    private static Message sPool;
    private static int sPoolSize = 0;
    private static final int MAX_POOL_SIZE = 10;
  }  

​ Message提供了obtain方法:通过obtain获取,可从MessagePool中获取(MessagePool类似数据库连接池)一个消息,可以节约开销。也通过myhanlder.obtain(),来获取一条target是myhanlder的对象的message。每条消息都有一个target,在某个handler发送消息(send或post)时,最终会将该handler赋值给该message.target,以便于在消息队列取出消息后直调用消息的target去处理消息。

MessagePool

​ 可以将创建的对象用完之后回收,以便再重复利用节约频繁创建释放开销。文章来源地址https://www.toymoban.com/news/detail-760531.html

public static void loop() {
       while (true) {
  //派发消息
  msg.target.dispatchMessage(msg);

  //消息处理完毕 回收
        msg.recycle();
    }
}     

public void recycle() {
       //回收Message 建立全局的MessagePool
       if (sPoolSize < MAX_POOL_SIZE) {
           next = sPool;
           sPool = this;
           sPoolSize++;
       }
}

到了这里,关于Android之handler消息处理机制详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Looper Handler 机制浅析

    最近想写个播放器demo,里面要用到 Looper Handler,看了很多资料都没能理解透彻,于是决定自己看看相关的源码,并在此记录心得体会,希望能够帮助到有需要的人。 本文会以 猜想 + log验证 的方式来学习 Android Looper Handler,对于一些复杂的代码会进行跳过,能够理解它们的设

    2024年02月11日
    浏览(26)
  • Android面试题精选——再聊Android-Handler机制-1,已开源

    下面想看Handler的工作流程图:(第一次画图,有点丑,凑合着看吧) 因为Handler的主要作用就是线程切换,所以在图中我把Handler线程变化也画了出来。从这张图我们能看出几点信息: **1、Handler负责消息的发送和处理:**Handler发送消息给MessageQueue和接收Looper返回的消息并且处理

    2024年04月12日
    浏览(32)
  • Handler原理机制解析,Android开发中的重要性

    Handler在android程序开发中使用的非常频繁、我们知道android是不允许在子线程中更新UI的,这就需要借助Handler来实现,那么你是否想过为什么一定要这个这样子做呢?而且Handler的内部消息处理机制究竟是什么样的呢?Handler的原理是需要通过源代码才能说的清楚的,而且它处理

    2024年02月06日
    浏览(25)
  • Android学习之路(13) Handler详解

    Handler是一套 Android 消息传递机制,主要用于线程间通信。 用最简单的话描述: handler其实就是主线程在起了一个子线程,子线程运行并生成Message,Looper获取message并传递给Handler,Handler逐个获取子线程中的Message. Binder/Socket用于进程间通信,而Handler消息机制用于同进程的线程间

    2024年02月09日
    浏览(28)
  • 【Android开发基础】多线程-Handle消息机制

    描述:一个静态的UI界面,如果需要同时加载多个资源,并能在视觉上得到动态反馈,就需要用到Handle消息机制。 知识点:Handle消息机制 难度:初级 理解 1、为什么要用Handle 根据官方规则:子线程不允许操作主线程中的组件 2、原理图 3、关键对象 (1)Message(消息类)   

    2024年02月09日
    浏览(29)
  • Android UI刷新机制与SurfaceView

    举例一个Activity的布局文件和逻辑如下: 当我们点击remove_btn时,会出现SurfaceView所在的区域会出现10s黑块的现象,这个现象在我们平时开发中用到SurafceView时常常遇到,往往在主线程同时存在耗时操作和SurfaceView detach操作的时候出现,那么为什么Surfaceview从parent view上面detach的

    2023年04月08日
    浏览(24)
  • 带你深入理解Android 中 UI 的刷新机制

    Android中的UI刷新机制是指Android系统如何更新和绘制UI界面以响应用户的操作和数据变化。UI的刷新过程涉及到多个关键概念和组件,包括主线程、UI线程、消息循环、View树、View的测量和布局、绘制等。下面将详细解释Android中的UI刷新机制,并提供相应的代码示例。 主线程和

    2024年02月14日
    浏览(25)
  • 高级UI之Android事件分发机制原理及源码分析

    在 Android 中, 事件分发机制是一块很重要的知识点, 掌握这个机制能帮你在平时的开发中解决掉很多的 View 事件冲突问题,这个问题也是面试中问的比较多的一个问题了, 本篇就来总结下这个知识点。 Android 中页面上的 View 是以树型结构显示的,View 会重叠在一起,当我们

    2024年02月08日
    浏览(24)
  • Android应用集成RabbitMQ消息处理指南

    RabbitMQ官网直通车 — ✈✈✈✈✈✈        最近工作繁忙,好久没有更新博文了。        对于互联网饱和的今天, 如何做到不同系统之间传递信息与通信? 在实际项目中,多个端例如:ios、android、pc、小程序采用从RabbitMQ上获取实时包消息,然后根据此实时包消息来

    2024年02月06日
    浏览(36)
  • Android-高级-UI-进阶之路-(二)-深入理解-Android-8-0-View-触摸事件分发机制,查漏补缺

    我们看到内部又调用了父类 dispatchTouchEvent 方法, 所以最终是交给 ViewGroup 顶级 View 来处理分发了。 顶级 View 对点击事件的分发过程 在上一小节中我们知道了一个事件的传递流程,这里我们就大致在回顾一下。首先点击事件到达顶级 ViewGroup 之后,会调用自身的 dispatchTouchE

    2024年04月14日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包