Android的消息处理机制

安卓之异步消息处理机制 安卓异步消息处理机制 阅读详情

在Android系统中,主线程用于处理Window及各种窗口上的输入事件,当然应用程序中的Activity、Broadcast Receiver等也是由主线程来处理。除了主线程之外,往往还有单独运行的线程,通常由开发者自己创建,用来做一些额外的工作,尤其是那种耗时的工作,这就需要Thread的子类来实现。

接口java.lang.Runnable代表着一小段执行的任务,由一个线程去调用执行。Runnable接口只有一个run(),子类将需要完成的任务放在该函数中。问题来了,通常在java.lang.Thread线程中没有消息循环,也就是说,在run函数中,通常是执行完处理之后,意味着流程结束,也就是线程结束。如果需要让线程长期存在去处理某种任务,需要自己写个while(){}循环,在循环中去执行需要完成的任务。在执行的过程中,通常会因为条件不满足而阻塞,条件满足后被唤醒执行。显然这整个过程需要开发者去判断,稍有不慎,将造成严重的后果。

1.简要介绍

Android提供了一种消息处理的机制,调用者将需要处理的任务发送到消息队列后返回,线程不断的从消息队列中读取消息,进行处理。这种消息驱动的方式,让系统中的任务处理变得灵活。因此,不难想象,这整个过程如下图所示,不断的向消息队列发送消息,从消息队列中取消息,并发送来执行。

因此需要如下几个要素:

Ÿ  消息的表示:Message

Ÿ  消息队列:MessageQueue

Ÿ  消息循环:Looper

Ÿ  消息处理:Handler

在介绍Android的消息处理机制之前,我们首先通过一个简单的例子,了解如果一个线程想要实现消息循环应该怎么做,如下是源码中给我们提供的一个例子,如此该线程便成为了一个Looper线程,不断的从消息队列中取消息,并调用mHandler的handleMessage处理消息。

class LooperThread extends Thread {

      public Handler mHandler;

 

      public void run() {

          Looper.prepare();

 

          mHandler = new Handler() {

              public void handleMessage(Message msg) {

                  // process incoming messages here

              }

          };

 

          Looper.loop();//开始循环,从消息队列中取消息,利用Handler去处理

      }

}

 

LooperThread.mHandler.sendMessage(msg);//消息发送

大家现在肯定会有如下疑惑,带着如下问题,我们去看Looper、Handler的源码。

1)      MessageQueue在哪儿?

2)      LooperThread是如何从MessageQueue取消息的?

3)      取到消息之后,是如何发送给mHandler的?

4)      他们之间的对应关系又是怎么样的?

2.Looper

在java层 native层均有Looper的实现,但其作用不一样。

2.1 Java层的Looper

首先来看Java层,其主要作用是将一个线程初始化为一个Looper线程,从MessageQueue中取消息发送给Handler执行。

     /** Initialize the current thread as a looper.

      * This gives you a chance to create handlers that then reference

      * this looper, before actually starting the loop. Be sure to call

      * {@link #loop()} after calling this method, and end it by calling

      * {@link #quit()}.

      */

    public static void prepare() {

        prepare(true);

    }

 

    private static void prepare(boolean quitAllowed[1]) {

        if (sThreadLocal.get() != null[2]) {

            throw new RuntimeException("Only one Looper may be created per thread");

        }

        sThreadLocal.set(new Looper(quitAllowed));

}

 

    private Looper(boolean quitAllowed) {

        mQueue[3] = new MessageQueue(quitAllowed);

        mThread = Thread.currentThread();

    }

代码很简单,但是需要解释三点:

1)      quitAllowed:是否允许消息队列退出

2)      prepare()会先检查该线程是否已经有了自己的Looper,若有则会抛出异常,即一个线程最多只能有一个Looper。

3)      Looper的构造函数中,新建了一个自己的MessageQueue对象,保存在成员mQueue,在loop()中对消息进行处理。

    /**

     * Run the message queue in this thread. Be sure to call

     * {@link #quit()} to end the loop.

     */

    public static void loop() {

        final Looper me = myLooper();

        if (me == null) {

            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");

        }

        final MessageQueue queue = me.mQueue;

 

        // Make sure the identity of this thread is that of the local process,

        // and keep track of what that identity token actually is.

        Binder.clearCallingIdentity();

        final long ident = Binder.clearCallingIdentity();

 

        for (;;) {

            Message msg = queue.next()[1]; // might block

            if (msg == null[2]) {

                // No message indicates that the message queue is quitting.

                return;

            }

 

            // This must be in a local variable, in case a UI event sets the logger

            Printer logging = me.mLogging;

            if (logging != null) {

             logging.println(">>>>> Dispatching to " + msg.target + " " +

                        msg.callback + ": " + msg.what);

            }

 

            msg.target.dispatchMessage(msg);

 

            if (logging != null) {

                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);

            }

 

            // Make sure that during the course of dispatching the

            // identity of the thread wasn't corrupted.

            final long newIdent = Binder.clearCallingIdentity();

            if (ident != newIdent) {

                Log.wtf(TAG, "Thread identity changed from 0x"

                   + Long.toHexString(ident) + " to 0x"

                   + Long.toHexString(newIdent) + " while dispatching to "

                   + msg.target.getClass().getName() + " "

                   + msg.callback + " what=" + msg.what);

            }

 

            msg.recycle();

        }

}

1)      Looper.loop()调用MessageQueue.next()从自己的消息队列中取出下一个消息,然后调用Handler的dispatchMessage(msg)将消息进行分发处理。其中next()可能会阻塞,例如消息队列为空,或者消息尚未准备好执行等等。

2)      若调用MessageQueue.next()返回空,不意味着消息队列为空,而是意味着此时调用了Looper.quit()。因此,当希望线程退出消息循环时,需要调用Looper.quit()函数。

/**********Looper.java***********/

public void quit() {

        mQueue.quit(false);

}

/***********MessageQueue.java************/

    void quit(boolean safe) {

        ……

            mQuitting = true;

……

    }

    Message next() {

        ……

// Process the quit message now that all pending messages have been handled.

                if (mQuitting) {

                    dispose();

                    return null;

                }

……

    }

Looper.java还有两个重要的函数,用来实现消息同步的,先不赘述,在MessageQueue中详细介绍

public int postSyncBarrier() {

        return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis());

    }

public void removeSyncBarrier(int token) {

        mQueue.removeSyncBarrier(token);

    }

2.2 Native层的Looper

android消息处理机制原理解析 android Handler Looper MessageQueue 阅读详情

相关推荐

Shopee 虾皮API接口:商品详情采集的实践

随着电商行业的蓬勃发展,数据采集和分析在商业决策中扮演着越来越重要的角色。Shopee作为东南亚领先的电商平台,拥有大量的商品数据。通过Shopee的API接口,我们可以方便地获取商品详情,为数据分析和市场研究提供有力支持。本文将介绍如何使用Shopee API接口采集商品详情,并分享一些实践技巧。提供了丰富的数据接口,包括商品详情、店铺信息、订单数据等。通过API接口,开发者可以轻松地获取Shopee平台上的数据,进行进一步的处理和分析。Shopee API接口:商品详情采集的实践与技巧。

An4480的博客 1888

Handler机制解析

待写

ahzhouxian的专栏 401

泛微Ecology9接口调用全流程:从配置到实战Java代码解析

本文详细解析了泛微Ecology9系统接口的完整调用流程,涵盖安全架构、服务端配置与客户端Java实战代码。重点阐述了基于RSA加密的认证机制、Token管理策略,并提供了企业级集成的核心代码示例与生产环境调优建议,帮助开发者安全、高效地实现系统对接。

m9n0o的博客 838

Android消息处理机制

Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。学习Android的消息处理机制,有几个概念(类)必须了解: 1.       Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。 2.       Message Queue 消息队列,用来存放通

ZhangLei的博客 1587

第一届“龙信杯”电子数据取证竞赛Writeup

第一届“龙信杯”电子数据取证竞赛Writeup

toto的博客 1万+

Graylog日志系统实战:高效接收与解析交换机日志

本文提供Graylog日志系统的实战部署与配置指南,重点讲解如何高效接收与解析交换机日志。通过Docker快速部署,配置Syslog输入,并指导华为、华三等主流交换机将日志发送至Graylog。文章还介绍了使用提取器解析日志字段、创建数据流进行分类,以及设置报警规则,实现从被动排查到主动预警的运维转变,帮助网络工程师构建集中、智能的日志管理系统。

weixin_29284885的博客 540

【学习】Android的消息机制

Android的消息机制主要指Handler的运行机制,而Handler的运行需要MessageQueue和Looper支撑 前置知识 MessageQueue:消息队列,内部以单链表的形式存储消息列表 Looper:以无限循环的模式查找是否有新消息,有则处理,无则等待 ThreadLocal:Looper中的一个概念,可以在每个线程中互不干扰地存储和提供数据 !线程默认没有Looper,要想使用handler就要先为线程创建looper,而主线程也就是UI线程(ActivityThread)被创建时就会初

PanicLin的博客 1068

密码学新手必看:三大顶级会议论文下载与阅读指南(附完整资源链接)

本文为密码学新手提供了系统性的三大顶级会议(Crypto、Eurocrypt、Asiacrypt)论文学习指南。内容涵盖如何高效获取最新论文资源、结构化精读论文的方法论,以及将理论转化为代码实践的路径,旨在帮助初学者快速构建密码学知识体系并应用于研究。

weixin_29214691的博客 319

Android:Android消息处理机制(详解)

Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。学习Android的消息处理机制,有几个概念(类)必须了解: 1.       Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。 2.       Message Queue 消息

HMYANG314的专栏 1553

图解电动汽车:电动汽车电控系统

电动汽车的电控系统通常包含三个子控制系统 —— 整车控制器、电池管理系统、驱动电机控制器。 整车控制器 VCU 整车控制器 VCU(Vehicle Control Unit)作为电动汽车的中央控制单元,是整个控制系统的核心,也是各个子系统的调控中心。VCU 的主要功能就是协调管理整车的运行状态,包括采集电机及电池状态,采集加速踏板信号、制动踏板信号、执行器及传感器信号,根据驾驶员的意图综合分析做出相应判定后,监控下层的各部件控制器的动作,它负责汽车的正常行驶、制动能量回馈、整车发动机及动力电池的能量管理、.

程序员「阿基米东」的编程之旅 1万+

Spine骨骼动画查看器 - Skeleton Viewer

骨骼动画是现代游戏和动画制作中常用的技术之一。Spine骨骼动画查看器(Skeleton Viewer)是一个官方提供的工具,用于查看和调试Spine骨骼动画。本文将介绍Skeleton Viewer的功能和使用方法,并提供相应的源代码示例。通过Skeleton Viewer,开发者可以直观地查看和调试Spine骨骼动画,包括骨骼结构、动画播放和事件触发等。这有助于提高骨骼动画的质量和效果,并加速开发过程。以上代码演示了如何使用Skeleton Viewer查看和播放Spine骨骼动画。

HsvvDatabase的博客 3461

安卓Handler消息处理机制详解

消息处理机制可以算得上是每个安卓开发入行最先接触的机制之一。它为我们提供了一种线程间通信方式。本文就讲解Handler提供的各种用法以及其运行机理。

lingchen881218的博客 2315

基于ESP32Cam摄像头+YOLOv3完成图像识别_355

本项目正是在此背景下提出,设计一个基于ESP32Cam摄像头的图像识别系统,通过WIFI热点通信实现图像数据的传输,并利用上位机(Windows与Android平台的QT APP)实时显示原始图像与识别结果,实现目标检测、识别与标注功能。

595

Android Handler消息处理机制

消息处理机制本质:一个线程开启循环模式持续监听并依次处理其他线程给它发的消息。简单的说:一个线程开启一个无限循环模式,不断遍历自己的消息列表,如果有消息就挨个拿出来做处理,如果列表没消息,自己就堵塞(相当于wait,让出cpu资源给其他线程),其他线程如果想让该线程做什么事,就往该线程的消息队列插入消息,该线程会不断从队列里拿出消息做处理。

轻口味的专栏 3404

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android 读写队列,详解Android 消息处理机制

摘要Android应用程序是通过消息来驱动的,当Android主线程启动时就会在内部创建一个消息队列。然后进入一个无限循环中,轮询是否有新的消息需要处理。如果有新消息就处理新消息。如果没有消息,就进入阻塞状态,直到消息循环被唤醒。那么在Android系统中,消息处理机制是怎么实现的呢?在程序开发时,我们经常会使用Handler处理Message(消息)。所以可以知道Handler是个消息处理者,M...

weixin_42370434的博客 2949

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

安卓消息处理机制

Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。学习Android的消息处理机制,有几个概念(类)必须了解: 1.       Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。 2.       Message Queue 消息

jinxinliu1的专栏 633

深入Android消息处理机制

摘要 Android应用程序是通过消息来驱动的,当Android主线程启动时就会在内部创建一个消息队列。然后进入一个无限循环中,轮询是否有新的消息需要处理。如果有新消息就处理新消息。如果没有消息,就进入阻塞状态,直到消息循环被唤醒。 那么在Android系统中,消息处理机制是怎么实现的呢?在程序开发时,我们经常会使用Handler处理Message(消息)。所以可以知道Handler是个消息处理者,Message是消息主体。除此之外还有消息队列和消息轮询两个角色。它们分别是MessageQueue和Loop

鸿蒙开发知识记录 582

Android消息处理机制简介

Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。学习Android的消息处理机制,有几个概念(类)必须了解: 1.       Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。 2.       Message Queue

569

android消息处理机制

下面和大家分享一下android中非常重要的消息处理机制,说到消息处理,Message,MessageQueue,Looper,Handler这四个类的作用是我们必须要明白的。 下面分别谈谈他们的作用:   MessageQueue MessageQueue表示消息队列,存放消息的地方,按照“先进先出”的规则执行,每一个线程只可以拥有一个MessageQueue。当创建Looper对象的时

qq942418300的专栏 1260

Android异步消息处理机制

Android异步消息处理机制:在Android中,只有主线程才能操作UI,但是主线程不能进行耗时操作,否则会阻塞线程,引起ANR异常。如果在子线程中要更新UI,一般是通过Handler发送消息,主线程接收消息并进行相应的逻辑处理,异步消息处理线程启动后,会进入一个无限的循环体中,每一次循环,从消息队列中取出一个消息,然后调用相应的消息处理函数,执行完成一个消息后则继续循环,若消息队列为空,线程则会

cy62423的博客 441

Android之异步消息处理机制

Android之异步消息处理机制 一,简介 Android 中的异步消息处理主要由四个部分组成,Message、Handler、MessageQueue和 Looper。 其中Message和Handler在上一小节中我们已经接触过了, 而MessageQueue和Looper 对于你来说还是全新的概念,下面我就对这四个部分进行一下简要的介绍。 1. Message Message 是

航天飞哥的博客 617

Android 消息处理机制

Android 消息处理机制 在 Android 中,主线程不可以做耗时操作,不然就会发生 ANR 异常,所以耗时操作只能在子线程中执行。在子线程执行完的结果,想要通知主线程进行更新或者进行某些操作呢?那么就要用到 Android 的异步消息机制,消息处理机制可以实现线程之间的交互。 Android消息处理机制的工作原理 消息处理的原理就,一个死循环线程不断获取消息队列里面消息,在子线程...

MVP的博客 296
ybelinda
博客等级 码龄18年 0粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值