• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理

Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理


Loop,Message,MessageQueue概念理解:

Message:Handler发送、接收和处理的消息对象

Looper:每个线程只能拥有一个Looper.它的looper()方法负责循环读取MessageQueue中的消息并将读取到的消息交给发送该消息的handler进行处理。

MessageQueue:消息队列,它采用先进先出的方式来管理Message。程序在创建Looper对象时,会在它的构造器中创建MessageQueue

Looper提供的源码如下:

private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
         mThread = Thread.currentThread();
     }

从源码第2行中可以看出,在创建Looper对象时会创建一个与之关联的MessageQueue对象。构造器是private修饰的,所以程序员是无法创建Looper对象的,就是说创建Looper同时就创建了MessageQueue对象

 

Handler:前面说Handler作用有两个---发送消息和处理消息,Handler发送的消息必须被送到指定的MessageQueue,也就是说,要想Handler正常工作必须在当前线程中有一个MessageQueue,否则消息没法保存。而MessageQueue是由Looper负责管理的,因此要想Handler正常工作,必须在当前线程中有一个Looper对象,这里分为两种情况:

1>主线程(UI线程),系统已经初始化了一个Looper对象,因此程序直接创建Handler即可
2>程序员自己创建的子线程,这时,程序员必须创建一个Looper对象,并启动它。

创建Looper:使用Looper.prepare(),查看源码

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));
    }
 
   private Looper(boolean quitAllowed) {
         mQueue = new MessageQueue(quitAllowed);
         mThread = Thread.currentThread();
     }

 

通过方法调用,第9行创建Looper对象,创建Looper对象时同时会创建MessageQueue对象(第13行)。此外,可以看出prepare()允许一个线程最多有一个Looper被创建

启动Looper:Looper.loop(),loop()使用一个死循环不断取出MessageQueue中的消息,并将消息发送给对应的Handler进行处理。下面是Looper类中looper()方法的部分源码

for (;;) {
              Message msg = queue.next(); // might block
              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
              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.recycleUnchecked();
        }
很明显第1行用了一个死循环,第2行从queue中取出Message,第15行通过dispatchMessage(Message msg)方法将消息发送给Handler。

Looper,MessageQueue,Handler的各自作用如下:

Looper:每个线程只有一个Looper,他负责管理MessageQueue,会不断的从MessageQueue中取出消息,将消息交给对应的Handler处理

MessageQueue:由Looper负责管理,是用来存放线程放入的消息。

Handler:它把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息

在线程中Handler的使用步骤是:

(1)调用 Looper的prepare()方法为当前线程创建Looper对象,创建Looper对象时,它的构造器会创建与之配套的MessageQueue。
(2)有了Looper之后,创建Handler子类的实例,重写HandlerMessage()方法,该方法负责处理来自其它线程的消息。
(3)调用Looper的loop()方法启动Looper。
 

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理

相关文章

  • 2017-05-26SDK manager.exe 运行时报错:系统找不到指定的文件 android.bat,sdkmanager.bat
  • 2017-05-26AndroidStudio怎样导入jar包,androidstudiojar
  • 2017-05-26getDrawingCache()和Android中的截图方法简介
  • 2017-05-26上传单个文件到多台机器工具
  • 2017-05-26一个大四毕业生想对自学Android的大学生说一些话,android大学生
  • 2017-05-26初识react native遇到的问题,reactnative
  • 2017-05-26android studio导入PullToRefresh教程
  • 2017-05-26安卓高级组件-----网格视图,安卓-----网格
  • 2017-05-26学习《第一行代码》使用实机测试所遇问题(一),《第一行代码》
  • 2017-05-26基于docker安装gitlab

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • [Android]数据篇,android数据
    • 硅谷社交3--登录页面,硅谷社交3--
    • eclipse安装genymotion插件。,eclipsegenymotion
    • Android焦点事件分发与传递机制
    • Android之DOM解析XML,androiddomxml
    • andriod 图片选择器,
    • 8.2.1 Bitmap(位图)全解析 Part 1
    • 利用zabbix监控国际线路的延迟情况
    • android列表停止滚动,加载图片,较为通用的一种办法,
    • 手机影音5--视频播放器的基本功能(2),5--基本功能

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有