也来解释一下android的MessageQueue源码
来源:互联网 发布:ubuntu永久挂载硬盘 编辑:程序博客网 时间:2024/05/19 11:46
大三了,老想自己写点市面上没有的东西,这些天在尝试写一个可以用鼠标操作手机的android应用,前段时间苦于找不到能在屏幕上产生触摸事件的方法,找了N久,发现一个Instrumentation类,觉得靠谱,就拿过来试一试。用的时候发现要在不同的线程里使用,于是我想是不是做个像android消息队列的结构,无信息要处理的时候线程等待,一旦有信息就立刻处理。
但是连猪跑都没见过,自己写一个谈何容易?想起在博客上看到的名言:“read the fucking source code!”一股“老子要读源码了”的屌丝优越感油然而生,于是对android的MessageQueue类做了下面的翻译和注释,翻译的过程中发现网上已经有了相似的东西,决知要躬行,最后还是自己又逐行读了一遍,其中不乏不懂之处,真心希望高手发现欠妥之处或看的我的疑问后不吝赐教!
/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.finetu.bo;import java.util.ArrayList;import android.os.Binder;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.os.SystemClock;import android.util.AndroidRuntimeException;import android.util.Config;import android.util.Log;/** * Low-level class holding the list of messages to be dispatched by a * {@link Looper}. Messages are not added directly to a MessageQueue, * but rather through {@link Handler} objects associated with the Looper. * * <p>You can retrieve the MessageQueue for the current thread with * {@link Looper#myQueue() Looper.myQueue()}. * * 底层类,用于维护一个message的列表,被一个Looper对象使用。Message对象并不直接加进MessageQueue中, * 但可以认为是通过Handler对象与Looper关联。 * * 调用Looper.mayQueue()可以得到当前线程的Message对象。 */public class MessageQueueOfAndroid { Message mMessages; //handler对象列表,个人理解为观察者列表 private final ArrayList mIdleHandlers = new ArrayList(); private boolean mQuiting = false; boolean mQuitAllowed = true; /** * Callback interface for discovering when a thread is going to block * waiting for more messages. * * 当进程将要等待更多Message而挂起时的回调接口。 */ public static interface IdleHandler { /** * Called when the message queue has run out of messages and will now * wait for more. Return true to keep your idle handler active, false * to have it removed. This may be called if there are still messages * pending in the queue, but they are all scheduled to be dispatched * after the current time. * * 当消息队列处理完所有的message需要等待更多message时调用本方法。当需要保持空闲Handler(这里的所 * 谓空闲Handler个人理解为做为观察者的Handler)活动状态时返回true,反之要移除时返回false。这个方 * 法有被调用时在消息队列中可能仍然有待处理的消息,但这些消息会在下一时刻被处理。 */ boolean queueIdle(); } /** * Add a new {@link IdleHandler} to this message queue. This may be * removed automatically for you by returning false from * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is * invoked, or explicitly removing it with {@link #removeIdleHandler}. * * <p>This method is safe to call from any thread. * * @param handler The IdleHandler to be added. * * 添加一个新的绑定当前消息队列的Handler对象。该对象被调用后可能会因为IdleHandler.queueIdle()方法返 * 回值为false而被自动移除,或者被removeIdlerHandler()方法显式移除。 * * 任何线程调用该方法都是安全的。 * * 参数:handler 要添加的Handler对象。 */ public final void addIdleHandler(IdleHandler handler) { if (handler == null) { throw new NullPointerException("Can't add a null IdleHandler"); } synchronized (this) { //向Handler列表中添加Handler对象 。 mIdleHandlers.add(handler); } } /** * Remove an {@link IdleHandler} from the queue that was previously added * with {@link #addIdleHandler}. If the given object is not currently * in the idle list, nothing is done. * * @param handler The IdleHandler to be removed. * * 从加入了Handler的队列中删除Handler对象,如果参数中的对象在列表中未找到,则什么也不做。 * */ public final void removeIdleHandler(IdleHandler handler) { synchronized (this) { mIdleHandlers.remove(handler); } } //空构造函数 MessageQueueOfAndroid() { } /** * */ final Message next() { boolean tryIdle = true; while (true) { long now;//记录当前时间 Object[] idlers = null;//Handler列表 // Try to retrieve the next message, returning if found. //尝试取出下一条消息,如果成功则返回 synchronized (this) { now = SystemClock.uptimeMillis();//把系统时间赋给now Message msg = pullNextLocked(now);//从当前的消息队列中拿出当前允许拿出的一个Message对象 if (msg != null) return msg;//对象不为空,返回 if (tryIdle && mIdleHandlers.size() > 0) {//拿到Handler的数组 idlers = mIdleHandlers.toArray(); } } // There was no message so we are going to wait... but first, // if there are any idle handlers let them know. //没有取出下一条消息,需要等待,但是首先,如果Handler数组中有Handler对象,则通知这些对象, boolean didIdle = false;//标记是否执行过Handler回调的标志位 if (idlers != null) { for (Object idler : idlers) { boolean keep = false; try { didIdle = true;//已有Handler调用了自己的queueIdle()方法,记录状态。 //消息队列需要等待,此处一次调用Handler对象的queueIdle()方法, //使得需要移出的Handler被移除,无需移出的被保存 keep = ((IdleHandler)idler).queueIdle(); } catch (Throwable t) { Log.wtf("MessageQueue", "IdleHandler threw exception", t); } if (!keep) { synchronized (this) { mIdleHandlers.remove(idler);//移除Handler的操作 } } } } // While calling an idle handler, a new message could have been // delivered... so go back and look again for a pending message. //当有Handler调用了回调函数时,可能恰好有一个消息加入了消息队列,所以需要让最上层的while循环 //重新循环一遍看有没有就绪的Messaged对象。(此处笔者不明白为何直接continue就可以做到这种功能, //因为对于有无新的Message,didIdle应该会有不同的状态,单位和这两种不同的状态可以代表有无Message对象,笔者不明白) if (didIdle) { tryIdle = false; continue; } synchronized (this) { // No messages, nobody to tell about it... time to wait! //没有消息了,此时已经不需要通知任何Handler对象,队列开始等待 try { if (mMessages != null) {//消息队列非空,说明有消息在一段可预知的时间后可以获取到,此时只需等待这一段有限的时间即可 if (mMessages.when-now > 0) { Binder.flushPendingCommands();//Binder操作,刷新什么不知道--" this.wait(mMessages.when-now);//等待已知的有限长时间 } } else {//否则,不知道何时会有新的Message可以拿到 Binder.flushPendingCommands(); this.wait();//持续等待 } } catch (InterruptedException e) { } } } } /** * 在message链表中取出当前时间下可取出的下一个Message对象,在一些特殊情况下,Message可以设置delay,来人 * 为延迟一段时间,这时不能立即取出队头的message对象,此处直接返回null。 */ final Message pullNextLocked(long now) { Message msg = mMessages; if (msg != null) { if (now >= msg.when) { mMessages = msg.next; if (Config.LOGV) Log.v( "MessageQueue", "Returning message: " + msg); return msg; } } return null; } /**通过when即时间,在message链表中插入新的message对象,参数msg.target==null作为执行quit操作的标识, * 插入前将msg的when属性用参数when赋值,若原本的链表为空,或when是最小的,则加在链表头,否则循环,找到一个合适 * 的位置插入msg,最后返回true。 */ final boolean enqueueMessage(Message msg, long when) { if (msg.when != 0) { throw new AndroidRuntimeException(msg + " This message is already in use."); } if (msg.target == null && !mQuitAllowed) { throw new RuntimeException("Main thread not allowed to quit"); } synchronized (this) { if (mQuiting) { RuntimeException e = new RuntimeException( msg.target + " sending message to a Handler on a dead thread"); Log.w("MessageQueue", e.getMessage(), e); return false; } else if (msg.target == null) { mQuiting = true; } msg.when = when; //Log.d("MessageQueue", "Enqueing: " + msg); Message p = mMessages; if (p == null || when == 0 || when < p.when) { msg.next = p; mMessages = msg; this.notify(); } else { Message prev = null; while (p != null && p.when <= when) { prev = p; p = p.next; } msg.next = prev.next; prev.next = msg; this.notify(); } } return true; } //重写的删除消息方法 final boolean removeMessages(Handler h, int what, Object object, boolean doRemove) { synchronized (this) { Message p = mMessages; boolean found = false; // Remove all messages at front. while (p != null && p.target == h && p.what == what && (object == null || p.obj == object)) { if (!doRemove) return true; found = true; Message n = p.next; mMessages = n; p.recycle(); p = n; } // Remove all messages after front. while (p != null) { Message n = p.next; if (n != null) { if (n.target == h && n.what == what && (object == null || n.obj == object)) { if (!doRemove) return true; found = true; Message nn = n.next; n.recycle(); p.next = nn; continue; } } p = n; } return found; } } //重写的删除消息方法 final void removeMessages(Handler h, Runnable r, Object object) { if (r == null) { return; } synchronized (this) { Message p = mMessages; // Remove all messages at front. while (p != null && p.target == h && p.callback == r && (object == null || p.obj == object)) { Message n = p.next; mMessages = n; p.recycle(); p = n; } // Remove all messages after front. while (p != null) { Message n = p.next; if (n != null) { if (n.target == h && n.callback == r && (object == null || n.obj == object)) { Message nn = n.next; n.recycle(); p.next = nn; continue; } } p = n; } } } //删除所有的Handler和Message final void removeCallbacksAndMessages(Handler h, Object object) { synchronized (this) { Message p = mMessages; // Remove all messages at front. while (p != null && p.target == h && (object == null || p.obj == object)) { Message n = p.next; mMessages = n; p.recycle(); p = n; } // Remove all messages after front. while (p != null) { Message n = p.next; if (n != null) { if (n.target == h && (object == null || n.obj == object)) { Message nn = n.next; n.recycle(); p.next = nn; continue; } } p = n; } } } /* private void dumpQueue_l() { Message p = mMessages; System.out.println(this + " queue is:"); while (p != null) { System.out.println(" " + p); p = p.next; } } */ //把控制权交给下一个等待的线程(对线程理解不深,仅供参考) void poke() { synchronized (this) { this.notify(); } }}
- 也来解释一下android的MessageQueue源码
- android源码解析--MessageQueue
- Android MessageQueue 源码笔记
- Android MessageQueue源码分析
- android MessageQueue 源码解析
- Android源码分析之MessageQueue
- 【从源码看Android】02MessageQueue的epoll原型
- 【从源码看Android】02MessageQueue的epoll原型
- Android 消息机制 - Handler, Looper, Message, MessageQueue 的源码分析
- Android源码浅析: Message/Handler/MessageQueue/Looper
- android handler Looper MessageQueue源码分析
- Android中Looper,MessageQueue,ThreadLocal源码解析
- 从源码来分析ThreadLocal、Message、Handler、Looper、MessageQueue
- 对android messagequeue的理解
- Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
- Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
- 也谈Android的学习和利用Android来赚钱
- 也谈Android的学习和利用Android来赚钱
- new [] 与new []()区别
- 网狐大厅介绍页js脚本错误
- 知名网站的技术实现
- 2013 吉林通化邀请赛 D-City 离线型的并查集
- 可伸缩性的10年探索:知名网站的技术发展历程
- 也来解释一下android的MessageQueue源码
- 黑马程序员-Java多线程-day12
- socket阻塞与非阻塞,同步与异步、I/O模型
- 大数据处理算法(非分布式处理)
- centos 6.0用yum安装中文输入法
- 游戏程序员具备
- 缓存设计,LIRS,cache锁粒度
- 电平柱状动态图
- 关于KMP算法当中的next函数