Android的handler消息机制
Hnadler机制中有这么几部分构成,包括 handler、Message、Looper和MessageQueue。要想在一个线程中使用Handler的话必须要有Looper和MessageQueue 的对象。在主线程中Looper不需要我们去创建 系统会自动帮我们调用prepareMainLooper和Looper.prepare方法,looper.prepare首先会到ThreadLocal这个线程级的单例中判断是否已经有了looper对象,如果有了就抛异常,如果没有就new出一个新的对象,并且通过ThreadLocal保存起来。这样就确保了我们的looper对象和当前线程建立起了一一对应的关系。looper对象new自己的时候调用构造方法会创建一个messageQueue对象,并且通过一个final类型的成员变量把MessageQueue保存起来。这样就确保了一个Looper对应唯一的messageQueue。所以 一个线程最多只能有一个looper, 一个looper对应唯一的MessageQueueu。也就是一个线程有唯一的Looper唯一的messageQueue。MessageQueue在创建的过程中会调用nativeInit方法,创建出一个nativeMessageQueue也就是说在jni层也有一个MessageQueue 创建NativeMessaageQueue的时候还会创建一个C++的Looper java层的MessageQueue和NativeMessageQueue通过一个成员变量mPtr建立起关联 mPtr保存了nativeMessageQueue的指针,我们可以通过这个指针随时访问nativeMessageQueue的首地址。需要注意 如果在主线程中调用Looper.prepareMainLooper或者Looper.prepare() 程序会抛出异常,因为系统已经帮我们创建好了无需我们在创建。
looper和messageQueue创建完成之后需要调用Looper.loop让消息循环起来。Looper.loop中有一个死循环,死循环不会阻塞主线程,而且恰恰是因为有这个死循环是我的主线程的代码不会执行完。handler不断的往消息队列中发消息 looper不断的取消息,如果没有消息就会睡在
Message msg = queue.next方法。实际上就是调用了nativeMessageQueue的方法, 利用到了linuxs的管道机制,取出消息之后就通过handler调用disPatchMessage来分发消息。他有三种情况:
如果msg的callback不为空 消息交给这个callback处理
如果msg的callback为空 判断handler mCallback接口 这个接口中就一个方法handleMessage
如果这个callback不为空交给这个handleMessage处理
如果上面两个都为空才交给handler的handleMessage处理消息
创建handler的时候 先到当前的线程中获取looper,如果当前线程没有looper的话那么会抛异常,如果当前线程已经创建了looper,那么我们把这个looper保存到一个final类型的成员变量中,通过这个Lopper找到对应的messageQueue,通过final成员变量进行保存这个messageQueue。这样就可以确保我们在哪个线程创建的handler,消息就会发送到对应的messageQueue中去。如果想在子线程中使用handler,必须首先调用looper.prepare()方法。
handler发送消息:
sendMessage sendEmptyMessage... 实际上都是调用 sendMessageAtTime这个方法,sendMessageAtTime调用了qnqueueMessage方法,这个党法实际上就是把消息放到消息队列中,
消息如何在消息队列中排序:
实际上Messagequeue通过一个成员变量 mMessage保存了消息队列的第一条消息,消息在消息队列中的排序是根据消息要执行的时间先后顺序进行排序。先执行的消息排在前面的,下一条消息通过message的next属性进行保存。enqueueMessage 就是根据新加入进来的消息 要执行的时间跟已有的消息进行比较找到合适的位置放到消息队列中。如果消息需要立即执行,那么就会执行nativeWake方法,实际上就是向管道中写了一个w 那么messageQueue的next方法就不会阻塞可以取出消息。
消息的创建和回收:
如果使用obtain方法来获取消息,那么就会利用到android的消息池。注意这个消息池是全局的,消息池的大小为50条。消息的回收,在Looper.loop()方法中当Handler处理消息之后会调用message.recycle方法回收消息。把要回收的消息所有的成员变量恢复到刚new出来的状态,然后放到消息池中去。
Android的handler消息机制的更多相关文章
- 【Android】Handler消息机制
Handler消息机制主要涉及Looper.Handler.MessageQueue.Message.其中,Looper主要负责获取消息,Handler负责发送消息及处理消息,MessageQueue ...
- Android消息传递之Handler消息机制
前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...
- Android Handler消息机制不完全解析
1.Handler的作用 Android开发中,我们经常使用Handler进行页面的更新.例如我们需要在一个下载任务完成后,去更新我们的UI效果,因为AndroidUI操作不是线程安全的,也就意味着我 ...
- Handler消息机制的一些原理(直接用code讲解)——Android开发
package com.example.handlertest; import android.os.Bundle; import android.os.Handler; import android ...
- Android Handler消息机制源码解析
好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础.下面我们分析一下Handler的源码实现. Handler消息机制有4个 ...
- Android全面解析之由浅及深Handler消息机制
前言 很高兴遇见你~ 欢迎阅读我的文章. 关于Handler的博客可谓是俯拾皆是,而这也是一个老生常谈的话题,可见的他非常基础,也非常重要.但很多的博客,却很少有从入门开始介绍,这在我一开始学习的时候 ...
- Android Handler 消息机制原理解析
前言 做过 Android 开发的童鞋都知道,不能在非主线程修改 UI 控件,因为 Android 规定只能在主线程中访问 UI ,如果在子线程中访问 UI ,那么程序就会抛出异常 android.v ...
- Handler消息机制与Binder IPC机制完全解析
1.Handler消息机制 序列 文章 0 Android消息机制-Handler(framework篇) 1 Android消息机制-Handler(native篇) 2 Android消息机制-H ...
- 浅析Android中的消息机制(转)
原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...
随机推荐
- js 计算两个日期之间 相差几年几月几日
1.计算日期差 Mine.vue <!-- 我的 --> <template> <div> <!-- 标题栏 --> <x-header :lef ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- hadoop生态系统学习之路(十)MR将结果输出到hbase
之前讲了MR将结果输出到hdfs.hive.db,今天再给大家分享一下,怎样将结果输出到hbase. 首先,提一句,笔者在hadoop集群运行此MR的时候报了一个错误.是一个jar包的缘故,这个错误是 ...
- Python爬虫开发【第1篇】【多线程爬虫及案例】
糗事百科爬虫实例: 地址:http://www.qiushibaike.com/8hr/page/1 需求: 使用requests获取页面信息,用XPath / re 做数据提取 获取每个帖子里的用户 ...
- CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+高速幂)
C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- 谈一谈以太坊虚拟机EVM的缺陷与不足
首先,EVM的设计初衷是什么?它为什么被设计成目前我们看的样子呢?根据以太坊官方提供的设计原理说明,EVM的设计目标主要针对以下方面: 简单性(Simplicity) 确定性(Determinism) ...
- 解决多次异步请求紊乱问题 - JavaScript
加入目前的需求这样的: 左边的菜单链接,点击后通过异步请求返回其HTML代码,然后innerHTML到右面的DIV中,加入切换菜单的速度非常快,最终会导致请求紊乱. 可以加入消息管理机制, ...
- C语言-1.static 和 extern使用,2.文件,3.数据块读写
1.static 和 extern使用, 1)修饰局部变量 static修饰局部变量特点:延长局部变量的生命周期 ,static修饰的局部变量只会被执行一次 extern不能修饰局部变量 2)修饰全局 ...
- bzoj1861 [Zjoi2006]Book 书架——splay
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1861 发现自己想splay的时候总是纠结那个点权是什么,因为splay原本是二分查找树... ...
- openpyxl操作excel
[转] openpyxl库可以读写xlsx格式的文件,对于xls旧格式的文件只能用xlrd读,xlwt写来完成了. python有很多模块都是用来操作excel的,比如xlrd,xlwt,pyExce ...