• 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 > android的消息机制

android的消息机制

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

网友通过本文主要向大家介绍了android消息推送机制,android消息处理机制,android消息传递机制,android消息发送机制,android事件分发机制等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android的消息机制


很多以前掌握的知识,总是慢慢的再忘记,看来还是自己理解的不够透彻,希望用博客的形式记录下来。

说起android的消息机制,那不得不提Handler,它的中文含义就是控制者,处理者。
安卓上的关于Handler的文档是这么写的:
Handler可以发送和处理Message,Runnable对象,并且与一个线程的MessageQueue关联。
当创建了Handler实例,它就会绑定在创建它线程的消息队列上。

这里写图片描述

首先在主线程中创建Handler的实例,与主线程的MessageQueue绑定,MessageQueue里有一个轮询器Looper,它会不断的查看消息队列是否有消息。如果有消息,就会把这个消息扔给Handler的handleMessage去处理。
这时,子线程拿到Handler对象,往主线程的MessageQueue发消息,消息队列就有了消息,就会把消息扔给handleMessage去处理消息。
上面的过程,听起来十分绕耳。为什么要这么做?在子线程中去处理不行吗?
我们知道子线程一般是用于处理耗时的操作,是不可以更新UI的。
因为多线程同时去draw,去操作UI界面,UI界面实在不好控制。操作UI的动作必须要由主线程去做。

所以在子线程中碰见需要更新UI,我们可以使用android为我们提供的Handler。它的出现主要就是为了解决在子线程中无法访问UI的矛盾。
而如果强行的在子线程去操作UI,可能会出现 “ android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.”的异常。

1,new Handler的时候,Handler究竟做了什么?
这里写图片描述

Looper.mylooper()
这里写图片描述
这里写图片描述
Looper对象是从ThreadLocal集合中get得到的。那什么时候,ThreadLocal把Looper对象set进去的呢?
这里写图片描述
在prepare方法中,创建了LoZ喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcGVyttTP86OssqLM7bzTtb3By7TmtKLXxUxvb3BlcrbUz/O1xFRocmVhZExvY2Fs1tChozxiciAvPg0KPGltZyBhbHQ9"这里写图片描述" src="http://www.bkjia.com/uploads/allimg/160407/04145QQ6-5.png" title="\" />
而在new Looper的同时,同样也创建了MessageQueue的实例。

而调用prepare方法的是prepareMainLooper。
在应用运行时,主线程ActivityThread产生并执行,而在主线程的main方法中,就会调用prepareMainLooper。
也就是说,在应用一启动,就会去创建Looper,MessageQueue对象。而在Handler的构造方法中,是拿到已经创建好的Looper和MessageQueue。

2,Message消息对象
new Message可以直接创建消息对象。
通过handler.obtainMessage(有许多重载的方法)可以创建消息,翻看源码可以得知,消息的创建全都是由obtain方法去处理。
这里写图片描述
这里的sPool表示的是消息池中的第一条消息,当消息池中没有消息时,就会new一个Message返回。
如果消息池中有的话,就废物利用,把消息池中的消息返回。
而消息池中的消息是由Message本身来维护的,而不是MessageQueue。
消息池中的消息是这样摆放的:
这里写图片描述
这里写图片描述
sPool表示是第一条消息,它指向着a。
Message m=sPool;
这时m也指向了a
sPool=m.next
sPool这时不再指向a,而是指向了下一个消息b。
m.next=null
sPoolSize--
a的next成员变量不再指向b,置为null。消息队列的长度减减,返回消息池中的消息。

3,Looper处理消息的过程
子线程发送消息后,主线程的MessageQueue就有了消息。而消息的扔给Handler去处理,是需要Looper来轮询的。
定位到Looper的轮询消息的loop方法。

 Message msg = queue.next(); // might block
 ..........
 ..........
 ..........           
 msg.target.dispatchMessage(msg);

从消息队列中取出的消息交由了msg.target这个成员变量的dispatchMessage方法。
而msg.target是Handler类型的。那msg.target是怎么传递进来的:

public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;

        return m;
    }

该handler在创建Message时,赋予给Handler类型的target。
而在dispatchMessage中,会调用handleMessage。
而在主线程中,我们定义的handleMessage就会覆盖该方法。
所以,Message对象就这样一步一步的传递到了主线程Handler的handleMessage中。
结论就是:消息是由哪个Handler发送的,就由哪个Handler去处理。

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

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

  • Android的消息机制,Android消息机制
  • Android 几种消息推送方案总结,android方案
  • Android消息机制
  • android的消息机制
  • Android中接收系统广播消息

相关文章

  • 2017-05-26zabbix 应用系列之nginx tcp stream监控
  • 2017-05-26java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE,apachemessagequeue
  • 2017-05-26统计nginx日志中各服务(目录)http总请求数、成功数、失败数的shell
  • 2017-05-26Android5.0开发范例大全 读书笔记(三),android5.0范例
  • 2017-05-26Android应用一般上架流程
  • 2017-05-26硅谷社交15--群详情,硅谷社交15--
  • 2017-05-26listview的ViewHolder优化,listviewviewholder
  • 2017-05-26Fiddler 手机抓包 手机联网异常解决方案,fiddler解决方案
  • 2017-07-22Android深入四大组件(四)广播的注册、发送和接收过程
  • 2017-05-26基于Nginx实现10万+并发,你应该做的Linux内核优化

文章分类

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

最近更新的内容

    • 用设计精美的阅读指读应用项目源码,设计精美源码
    • VMware中ubuntu忘记密码的解决办法(转)
    • Android 之 Intent(意图),androidintent意图
    • Android环境搭建和编写helloworld,androidhelloworld
    • Linux目录与文件权限的意义
    • Android动态加载Activity原理
    • 去除GridView选中时的蓝色背景,gridview选中蓝色
    • 4.4.2 ContentProvider再探——Document Provider
    • Docker+Redis3集群环境搭建
    • 安卓四大组件之广播,安卓四大组件

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

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