【Android消息机制】简要分析(一)
来源:互联网 发布:淘宝怎么更换图片 编辑:程序博客网 时间:2024/06/05 02:51
主要组成概述:Hanlder、MessageQueue以及Looper
1.Handler:线程切换
2.MessageQueue:用来存储信息 内部实现是单链表而不是队列。
3.Looper:无限循环的方式去查找是否有消息
备注:Looper中一个ThreadLocal的概念
作用:是来存储每一个线程中数据。
用途:Hanlder创建的时候会采用当前线程的Looper来构造消息循环系统,Handler正式通过ThreadLocal来获取当前的线程Looper的。
源代码
1.Handler是如何将三者联系起来的?
看看Handler创建源代码:
public Handler(Callback callback, boolean async) { ...//省略 mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
到调用了Looper.myLooper()
我们点进看看:
/** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ public static Looper myLooper() { return sThreadLocal.get(); }
没错,的确是这样印证了Handler、Looper的关系。
那么MessageQueue是如何一起协同工作呢?
我们看到mQueue = mLooper.mQueue;
所以从不难推断出MessageQueue在Looper初始化的时候也一并初始化了。
从这里我们也可以看出:无论我们在主线程创建多少个Handler,他们公用一个消息队列的
2.Looper是如何工作的?
上面概述的时候我们知道,Looper是负责从消息队列中读取消息,然后回传到handler的handleMessage方法来处理消息的。
大家不知道还记不记得,我们是如何在子线程创建一个Handler的? 我们需要调用Looper.prepare()来准备一个Looper,并且调用Looper.loop()。
很明显Looper.loop()就是无限读取消息队列的奥秘所在。
源代码(省略了部分):
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static void loop() { 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; ... for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ... msg.target.dispatchMessage(msg); ... } } /** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ public static Looper myLooper() { return sThreadLocal.get(); }
第一步:先调用了Looper.myLooper()这个方法,返回当前线程所在的Looper实例。备注:这里也刚好可以看到了ThreadLocal的用途了。
第二步:无限死循环 如果有消息来了就:msg.target.dispatchMessage(msg);
这个msg.target是什么呢? 通过Message源代码发现 就是发送这个msg对象的Handler实例: Handler target;
那msg是什么时候保存的呢?通过Handler源代码发现:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
msg在入队前,保存了这个handler实例的引用。
然后调用了这个Hanlder实例的dispatchMessage的方法。
那我们来看看Handler的dispatchMessage做了什么:
/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
我们看到一句很重点的:handleMessage(msg);
实际上他是一个空方法:
public void handleMessage(Message msg) { }
这个就是为什么我们创建Handler之后要重写这个方法来处理消息了。
-Hans 2016.2.25 23:45
- 【Android消息机制】简要分析(一)
- Android的消息机制简要分析
- Android实现机制分析(一)——消息机制
- Android架构分析之Android消息处理机制(一)
- Android消息处理机制源码分析(一):整体过程
- Android-消息机制(一):过程及源码分析
- Android -- Vold机制简要分析
- Android -- Vold机制简要分析
- Android -- Vold机制简要分析
- Android 消息机制(一)
- Android消息机制分析
- Android消息机制分析
- Android消息机制(一)
- Android消息机制(一)
- Android消息机制(一)
- Android消息机制(一)
- android handler机制的简要分析
- Android触摸事件传递机制简要分析
- Drawable 着色的后向兼容方案
- 资格考试_第二章_证券投资基金概述
- iOS开发中UICollectionView的使用方法
- leetcode-140-Word Break II
- 【hdu1312】red and black——bfs
- 【Android消息机制】简要分析(一)
- Java连接Redis
- 警告:检测到时钟错误。您的创建可能是不完整的。
- python Django后台开发笔记11
- 第五天 App编程开发【跟着大磨马学IT编程(安卓java)】
- Android布局优化 merge标签使用
- 安卓webView实现长按二维码的自动识别功能
- linux下删除mysql
- linux(ubuntu)2台互相ssh无密码访问