返回顶部
首页 > 资讯 > 精选 >Android消息机制Handler如何使用
  • 581
分享到

Android消息机制Handler如何使用

2023-06-21 20:06:58 581人浏览 薄情痞子
摘要

这篇文章主要介绍“Android消息机制Handler如何使用”,在日常操作中,相信很多人在Android消息机制Handler如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android消息机制Ha

这篇文章主要介绍“Android消息机制Handler如何使用”,在日常操作中,相信很多人在Android消息机制Handler如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android消息机制Handler如何使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    概述

    Handler是Android消息机制的上层接口。通过它可以轻松地将一个任务切换到Handler所在的线程中去执行。通常情况下,Handler的使用场景就是更新UI。

    Handler的使用

    在子线程中,进行耗时操作,执行完操作后,发送消息,通知主线程更新UI。

    public class Activity extends android.app.Activity {private Handler mHandler = new Handler(){@Override                public void handleMessage(Message msg) {super.handleMessage(msg);// 更新UI}};@Override    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {super.onCreate(savedInstanceState, persistentState);setContentView(R.layout.activity_main);new Thread(new Runnable() {@Override                         public void run() {// 执行耗时任务                ...                // 任务执行完后,通知Handler更新UI                Message message = Message.obtain();message.what = 1;mHandler.sendMessage(message);}}).start();}}

    Handler架构

    Handler消息机制主要包括:MessageQueue、Handler、Looper这三大部分,以及Message。

    • Message:需要传递的消息,可以传递数据;

    • MessageQueue:消息队列,但是它的内部实现并不是用的队列,而是通过单链表数据结构来维护消息列表,因为单链表在插入和删除上比较有优势。主要功能是向消息池投递消息( MessageQueue.enqueueMessage)和取走消息池的消息( MessageQueue.next)。

    • Handler:消息辅助类,主要功能是向消息池发送各种消息事件( Handler.sendMessage)和处理相应消息事件( Handler.handleMessage);

    • Looper:消息控制器,不断循环执行( Looper.loop),从MessageQueue中读取消息,按分发机制将消息分发给目标处理者。

    Android消息机制Handler如何使用

    从上面的类图可以看出:

    • Looper有一个MessageQueue消息队列;

    • MessageQueue有一组待处理的Message;

    • Message中记录发送和处理消息的Handler;

    • Handler中有Looper和MessageQueue。

    MessageQueue、Handler和Looper三者之间的关系: 每个线程中只能存在一个Looper,Looper是保存在ThreadLocal中的。 主线程(UI线程)已经创建了一个Looper,所以在主线程中不需要再创建Looper,但是在其他线程中需要创建Looper。 每个线程中可以有多个Handler,即一个Looper可以处理来自多个Handler的消息。 Looper中维护一个MessageQueue,来维护消息队列,消息队列中的Message可以来自不同的Handler。

    Android消息机制Handler如何使用

    Handler的运行流程

    在子线程执行完耗时操作,当Handler发送消息时,将会调用 MessageQueue.enqueueMessage,向消息队列中添加消息。 当通过 Looper.loop开启循环后,会不断地从消息池中读取消息,即调用 MessageQueue.next, 然后调用目标Handler(即发送该消息的Handler)的 dispatchMessage方法传递消息, 然后返回到Handler所在线程,目标Handler收到消息,调用 handleMessage方法,接收消息,处理消息。

    Android消息机制Handler如何使用

    源码分析

    在子线程创建Handler

    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之前,要调用 Looper.prepare()方法,Handler创建后,还要调用 Looper.loop()方法。而前面我们在主线程创建Handler却不要这两个步骤,因为系统帮我们做了。

    主线程的Looper

    在ActivityThread的main方法,会调用 Looper.prepareMainLooper()来初始化Looper,并调用 Looper.loop()方法来开启循环。

    public final class ActivityThread extends ClientTransactionHandler {// ...    public static void main(String[] args) {// ...        Looper.prepareMainLooper();// ...        Looper.loop();}}

    Looper

    从上可知,要使用Handler,必须先创建一个Looper。

    初始化Looper:

    public final class Looper {public static void prepare() {prepare(true);}private static void prepare(Boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}sMainLooper = myLooper();}}private Looper(Boolean quitAllowed) {MQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread();}// ...}

    从上可以看出,不能重复创建Looper,每个线程只能创建一个。创建Looper,并保存在 ThreadLocal。其中ThreadLocal是线程本地存储区(Thread Local Storage,简称TLS),每个线程都有自己的私有的本地存储区域,不同线程之间彼此不能访问对方的TLS区域。

    开启Looper

    public final class Looper {// ...    public static void loop() {// 获取TLS存储的Looper对象        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;// 进入loop主循环方法        for (;;) {Message msg = queue.next();// 可能会阻塞,因为next()方法可能会无线循环            if (msg == null) {// 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            final Printer logging = me.mLogging;if (logging != null) {logging.println(">>>>> Dispatching to " + msg.target + " " +                                                        msg.callback + ": " + msg.what);}// ...            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;final long dispatchEnd;try {// 获取msg的目标Handler,然后分发Message                msg.target.dispatchMessage(msg);dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;}finally {if (traceTag != 0) {Trace.traceEnd(traceTag);}}// ...            msg.recycleUnchecked();}}}

    Handler

    创建Handler:

    public class Handler {// ...    public Handler() {this(null, false);}public Handler(Callback callback, Boolean async) {// ...        // 必须先执行Looper.prepare(),才能获取Looper对象,否则为null        mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException(                      "Can't create handler inside thread " + Thread.currentThread()                              + " that has not called Looper.prepare()");}mQueue = mLooper.mQueue;// 消息队列,来自Looper对象        mCallback = callback;// 回调方法        mAsynchronous = async;// 设置消息是否为异步处理方式}}

    发送消息:

    子线程通过Handler的post()方法或send()方法发送消息,最终都是调用 sendMessageAtTime()方法。

    post方法:

    public final Boolean post(Runnable r){return sendMessageDelayed(getPostMessage(r), 0);}public final Boolean postAtTime(Runnable r, long uptimeMillis){return sendMessageAtTime(getPostMessage(r), uptimeMillis);}public final Boolean postAtTime(Runnable r, Object token, long uptimeMillis){return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);}public final Boolean postDelayed(Runnable r, long delayMillis){return sendMessageDelayed(getPostMessage(r), delayMillis);}private static Message getPostMessage(Runnable r) {Message m = Message.obtain();m.callback = r;return m;}

    send方法:

    public final Boolean sendMessage(Message msg){return sendMessageDelayed(msg, 0);}public final Boolean sendEmptyMessage(int what){return sendEmptyMessageDelayed(what, 0);}public final Boolean sendEmptyMessageDelayed(int what, long delayMillis) {Message msg = Message.obtain();msg.what = what;return sendMessageDelayed(msg, delayMillis);}public final Boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {Message msg = Message.obtain();msg.what = what;return sendMessageAtTime(msg, uptimeMillis);}public final Boolean sendMessageDelayed(Message msg, long delayMillis){if (delayMillis < 0) {delayMillis = 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);}sendMessageAtTime()public Boolean sendMessageAtTime(Message msg, long uptimeMillis) {MessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(                      this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}return enqueueMessage(queue, msg, uptimeMillis);}private Boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {msg.target = this;if (mAsynchronous) {msg.setAsynchronous(true);}return queue.enqueueMessage(msg, uptimeMillis);}

    分发消息

    在loop()方法中,获取到下一条消息后,执行 msg.target.dispatchMessage(msg),来分发消息到目标Handler。

    public class Handler {// ...    public void dispatchMessage(Message msg) {if (msg.callback != null) {// 当Message存在回调方法,调用该回调方法            handleCallback(msg);} else {if (mCallback != null) {// 当Handler存在Callback成员变量时,回调其handleMessage()方法                if (mCallback.handleMessage(msg)) {return;}}// Handler自身的回调方法            handleMessage(msg);}}private static void handleCallback(Message message) {message.callback.run();}}

    到此,关于“Android消息机制Handler如何使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: Android消息机制Handler如何使用

    本文链接: https://lsjlt.com/news/300748.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Android消息机制Handler如何使用
      这篇文章主要介绍“Android消息机制Handler如何使用”,在日常操作中,相信很多人在Android消息机制Handler如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android消息机制Ha...
      99+
      2023-06-21
    • Android Handler消息机制分析
      目录Handler是什么?Handler 的基本使用用法一:通过 send 方法用法二:通过 post 方法Handler 类MessageQueue 类Looper 类Handle...
      99+
      2024-04-02
    • Android消息机制Handler用法总结
      1.简述 Handler消息机制主要包括: MessageQueue、 Handler、 Looper、Message。 Message:需要传递的消息,可以传递数据; ...
      99+
      2024-04-02
    • Android中Handler消息传递机制
      Handler 是用来干什么的? 1)执行计划任务,可以在预定的时间执行某些任务,可以模拟定时器 2)线程间通信。在Android的应用启动时,会创建一个主线程,主线程会创建...
      99+
      2022-06-06
      handler Android
    • Android消息机制Handler用法有哪些
      这篇文章主要讲解了“Android消息机制Handler用法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android消息机制Handler用法有哪些”吧!1.简述Handler消息...
      99+
      2023-06-21
    • handler+message【消息机制】
      🍖🍖 作者 : 不良使 🍖🍖🍖🍖 潜力创作新星 华为云享专家 🍖🍖&...
      99+
      2023-09-18
      android
    • 学习Android Handler消息传递机制
      Android只允许UI线程修改Activity里的UI组件。当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理...
      99+
      2022-06-06
      handler Android
    • Android消息机制Handler深入理解
      目录概述Handler的使用Handler架构Handler的运行流程源码分析在子线程创建Handler主线程的LooperLooperHandler分发消息总结概述 Handler...
      99+
      2024-04-02
    • Android handler异步消息机制是什么
      Android中的Handler是一种基于消息机制的异步处理机制。它可以用来将消息或Runnable对象发送到主线程或者后台线程中执...
      99+
      2023-10-18
      Android
    • android线程消息机制之Handler详解
      android线程消息机制主要由Handler,Looper,Message和MessageQuene四个部分组成。平常在开发中,我们常用来在子线程中通知主线程来更新,其实整个安卓生命周期的驱动都是通过Handler(ActivityThr...
      99+
      2023-05-30
      android 线程消息机制 handler
    • Android Handler消息派发机制源码分析
      注:这里只是说一下sendmessage的一个过程,post就类似的 如果我们需要发送消息,会调用sendMessage方法 public final boolean s...
      99+
      2022-06-06
      handler 源码 Android
    • Android消息处理机制Looper和Handler详解
      Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。 Handler:处理者,负责Messag...
      99+
      2022-06-06
      looper handler Android
    • 掌握Android Handler消息机制核心代码
      目录一、handler基本认识1、基本组成2、基本使用方法3、工作流程二、发送消息 三、消息进入消息队列1、入队前的准备工作2、将消息加入队列四、从消息队列里取出消息1、准备工作2、...
      99+
      2024-04-02
    • Android 消息机制以及handler的内存泄露
      Handler 每个初学Android开发的都绕不开Handler这个“坎”,为什么说是个坎呢,首先这是Android架构的精髓之一,其次大部分人都是知其然却不知其所以然。今...
      99+
      2022-06-06
      消息机制 handler Android
    • Android消息机制Handler的工作过程详解
      综述   在Android系统中,出于对性能优化的考虑,对于Android的UI操作并不是线程安全的。也就是说若是有多个线程来操作UI组件,就会有可能导致线程安全问题。所以在A...
      99+
      2022-06-06
      handler Android
    • android学习笔记之handler消息处理机制1
      在andorid中,一个进程中最少也有一个线程,一般来说,有一个主线程(也就UI线程);以及多个子线程(也叫Worker线程)。 在androi...
      99+
      2022-06-06
      android学习 handler Android
    • Android的消息机制
      一、简介 Android的消息机制主要是指Handler的运行机制,那么什么是Handler的运行机制那?通俗的来讲就是,使用Handler将子线程的Message放入主线程的...
      99+
      2022-06-06
      消息机制 Android
    • Android消息机制基本原理和使用
      在Android开发过程中,我们常常遇到子线程更新UI的需求,例如在子线程进行耗时较长的下载,等下载完成之后,再去更新UI,提示用户下载完成,直...
      99+
      2022-06-06
      Android
    • android的消息处理机制(图文+源码分析)—Looper/Handler/Message
      这篇文章写的非常好,深入浅出,关键还是一位大三学生自己剖析的心得。这是我喜欢此文的原因。下面请看正文: 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学...
      99+
      2022-06-06
      message looper handler 源码 Android
    • Android中消息机制分析
      本文中的源码基于Android 29; 一、概述 对于Android开发者而言,我们处理异步消息用的最多的也是轻车熟路的一种方式,就是使用Handler进行消息的分发和处理。但...
      99+
      2022-06-06
      消息机制 Android
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作