android Handle
2016-03-11 10:41
435 查看
什么是Handler消息机制?
Android中为我们定义好的一套线程间数据共享与通信的框架。它包含一套完整的数据结构定义(Handler、Looper、Message、MessageQueue)和调用逻辑。
Handle类的作用:
在新启动的线程中发送消息。
在主线程中获取,处理消息
类角色简要描述(Java层)
Handler:使用接口,发送消息到消息队列,重写方法处理消息
Message:消息数据的封装
Looper:线程本地变量,完成消息循环
MessageQueue:消息队列,存放消息,并与底层交互
工作模型简述
Handler将消息发送到MessageQueue消息队列中
Looper对消息队列进行管理,从消息队列中进行取消息
取出的消息由对应的Handler进行分发和处理
为什么需要Handler消息机制?
线程间数据共享与通信
Android的单线程UI模型
有序操作
消息循环
我们可以调用Looper类的loop函数使线程进入到一个消息循环中。之后就不断地去消息队列中获取消息:
如果有消息需要处理就将消息返回处理;
如果没有消息需要处理就会通过JNI调用C++层的pollInner函数进行睡眠等待。
线程处于睡眠状态又是如何被唤醒的呢?
在创建C++层的Looper的时候,会创建一个管道,管道其实就是个文件,用于进程间通信;
将这个管道的读端文件描述符和写端文件描述符保存到该Looper的成员变量中;
最后对管道注册监听事件。
出来清空管道。之后Looper就会将消息取出,实现消息循环。不是我们所关心的事件,如果是就会唤醒Looper所在的线程,并将管道内容读取出来清空管道。之后Looper就会将消息取出,实现消息循环。
消息发送
调用Handler的成员函数来发送一个Message或Runnable对象。在发送消息时,是可以指定消息的处理时间的,如果没有指定默认为立即处理。
Handler的内部成员变量mQueue将消息放入消息队列中,在放入队列之前将发送消息的Handler赋给Message的变量target。
把消息加入到消息队列时,根据消息的处理时间进行排序:
当加入的消息在目标消息队列头部时,执行唤醒操作;
当加入的消息在目标消息队列中间时,不需要唤醒线程。
当需要唤醒线程时,我们通过在C++层的Looper向写端文件描述符写入一个字符,我们在前面已经注册了管道的监听事件,所以这个时候目标线程就会因为这个管道 发生了一个事件而被唤醒
消息处理
消息从MessageQueue中取出后,会交给target的dispatchMessage函数分发。
前面我们知道消息的成员变量target指向的是一个Handler对象,所以就调用Handler的dispatchMessage分发消息。
Handler类的成员函数dispatchMessage按照以下顺序来分发一个消息:
Handler发送一个Runnable对象时msg.callback不为空,之后handleCallback函数就会调用Runnable的run函数。
mCallback是Handler内部接口Callback的实现类的对象,一般为null。否则调用该接口的handleMessage函数。
如果前面两个条件都不满足,最后调用Handler的handleMessage,一般由子类重写。
Android中为我们定义好的一套线程间数据共享与通信的框架。它包含一套完整的数据结构定义(Handler、Looper、Message、MessageQueue)和调用逻辑。
Handle类的作用:
在新启动的线程中发送消息。
在主线程中获取,处理消息
类角色简要描述(Java层)
Handler:使用接口,发送消息到消息队列,重写方法处理消息
Message:消息数据的封装
Looper:线程本地变量,完成消息循环
MessageQueue:消息队列,存放消息,并与底层交互
工作模型简述
Handler将消息发送到MessageQueue消息队列中
Looper对消息队列进行管理,从消息队列中进行取消息
取出的消息由对应的Handler进行分发和处理
为什么需要Handler消息机制?
线程间数据共享与通信
Android的单线程UI模型
有序操作
消息循环
我们可以调用Looper类的loop函数使线程进入到一个消息循环中。之后就不断地去消息队列中获取消息:
如果有消息需要处理就将消息返回处理;
如果没有消息需要处理就会通过JNI调用C++层的pollInner函数进行睡眠等待。
线程处于睡眠状态又是如何被唤醒的呢?
在创建C++层的Looper的时候,会创建一个管道,管道其实就是个文件,用于进程间通信;
将这个管道的读端文件描述符和写端文件描述符保存到该Looper的成员变量中;
最后对管道注册监听事件。
出来清空管道。之后Looper就会将消息取出,实现消息循环。不是我们所关心的事件,如果是就会唤醒Looper所在的线程,并将管道内容读取出来清空管道。之后Looper就会将消息取出,实现消息循环。
消息发送
调用Handler的成员函数来发送一个Message或Runnable对象。在发送消息时,是可以指定消息的处理时间的,如果没有指定默认为立即处理。
Handler的内部成员变量mQueue将消息放入消息队列中,在放入队列之前将发送消息的Handler赋给Message的变量target。
把消息加入到消息队列时,根据消息的处理时间进行排序:
当加入的消息在目标消息队列头部时,执行唤醒操作;
当加入的消息在目标消息队列中间时,不需要唤醒线程。
当需要唤醒线程时,我们通过在C++层的Looper向写端文件描述符写入一个字符,我们在前面已经注册了管道的监听事件,所以这个时候目标线程就会因为这个管道 发生了一个事件而被唤醒
消息处理
消息从MessageQueue中取出后,会交给target的dispatchMessage函数分发。
前面我们知道消息的成员变量target指向的是一个Handler对象,所以就调用Handler的dispatchMessage分发消息。
Handler类的成员函数dispatchMessage按照以下顺序来分发一个消息:
Handler发送一个Runnable对象时msg.callback不为空,之后handleCallback函数就会调用Runnable的run函数。
mCallback是Handler内部接口Callback的实现类的对象,一般为null。否则调用该接口的handleMessage函数。
如果前面两个条件都不满足,最后调用Handler的handleMessage,一般由子类重写。
相关文章推荐
- Android RecyclerView完全解析
- Android 短信监听
- android邮件发送几种方式
- Android Studio添加assets文件夹
- Android Menu的基本用法
- Android事件处理之基于监听的事件处理
- failed to find target with hash string 'android-23'
- android图片加载—二级缓存
- Android深入浅出系列之Socket—Socket编程(二)
- Android N分屏模式Activity生命周期的变化
- base64(Bitmap和base64的互换)
- Android项目开发(4)-忘记密码---验证码验证页面功能实现
- android程序点击返回退出时,返回到欢迎界面的解决办法
- Android studio中自定义属性访问不了的解决办法
- Android深入浅出系列之Socket—Socket编程(一)
- Android项目开发(3)-注册验证码验证页面功能实现
- android canvas 绘图笔记
- 百度地图加载不出来,问题根源在SHA1
- Android项目开发(2)-注册手机验证知识总结
- android xml文件不显示视图的问题