转载请声明出处:http://blog.csdn.net/qq_24692041/article/details/68066025
Android线程间通讯方式有很多,但是大部分内部实现其实都是handler。今天我们就来看看handler的内部实现机制,实现原理,实现细节。本文主要是为了搞清楚线程间的通讯,Message也可以用于进程间的通讯,在本文中不对此进行详细的讲解,浅尝辄止!后面如果有需要,我会补上Message的进程间通讯相关文章,敬请期待!
本位我们分步骤对Handler消息机制进行分析,这样有条理一点,已更利于阅读。
Handler进程间通讯主要关联了Thread,ThreadLocal,Handler,Message,MessageQueue,Looper,,这几个类在内。我们先看看这几个类各自在这个实现工程中扮演者什么样的角色!
Thread:整个机制产生的意义,所有这个机制就是为Thread服务!Looper的创建是为Thread而创建,其实是Thread持有。Handler使用的Looper是由Thread提供!
ThreadLocal:Thread属性的存储者,内部维护一个ThreadLocalMap,其中存放了Thread的所有属性,Looper就是存放在这儿。
Handler:消息的发起者,发出一个消息。消息的处理者,消息处理的时间到了对该消息进行处理。必须有一个Looper,通过操作Looper持有的MessageQueue实现消息的发送,当Looper通知处理Message的时候,对Message进行处理。
Message:数据和信号携带者,携带数据进行传递。处理时机决定者,通过when属性决定消息的处理时间。消息队列的产生者,将一个个的message对象串联起来,形成消息队列。
MessageQueue:消息存放者,存放了一个消息队列,有消息进来的时候安插在指定的位置,需要处理的时候将消息取出来。消息排队者,将消息按处理的时间进行存放,让消息排队进行处理。
Looper:运行机制全局掌控者,让整个机制活动起来的关键人员,将所有角色联系起来,根据具体实现进行调度,完成整个机制的任务。内部持有一个MessageQueue,
Handler通过关联Looper,联系上MessageQueue。
public class Handler { private static final boolean FIND_POTENTIAL_LEAKS = false; private static final String TAG = "Handler"; //当前handler所在线程的looper final Looper mLooper; //跟looper对应的消息队列 final MessageQueue mQueue; //处理消息的回调 final Callback mCallback; //决定处理消息的方式同步的还是异步的 final boolean mAsynchronous; IMessenger mMessenger; /** * 通过设置这个接口去处理消息,就不需要再定义一个Handler的子类 */ public interface Callback { public boolean handleMessage(Message msg); } /** * Subclasses must implement this to receive messages. * Message和Handler都没有callback才会调用处理消息,这儿啥也没做,留着口给子类去完成了 */ public void handleMessage(Message msg) { } /** * 处理系统消息 * Handle system messages here. */ public void dispatchMessage(Message msg) { //如果msg有回调就交给msg处理 if (msg.callback != null) { handleCallback(msg); } else { //msg没有回调,创建Handler的时候有给回调就交给这个回调处理 if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } //调用自己的handleMessage方法处理,什么也没做,交给子类去具体实现,具体操作。平时我们用的匿名内部类的方式就是走了这一步 handleMessage(msg); } } public Handler() { this(null, false); } /** * 构造方法,设定消息处理回调,如果当前线程中没有Looper的时候,将接不到消息,还会抛出异常 */ public Handler(Callback callback) { this(callback, false); } /** * 构造方法,指定一个Looper,用这个Looper替换默认的Looper */ public Handler(Looper looper) { this(looper, null, false); } public Handler(Looper looper, Callback callback) { this(looper, callback, false); } /** * 设定当前Handler是同步处理消息还是异步处理消息 */ public Handler(boolean async) { this(null, async); } /** * 构造方法,初始化 */ public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } //获取一个Looper,UI线程系统自动调用prepareMainLooper方法,创建了UI线程的looper //如果Handler在子线程中创建,必须先调用prepare创建一个looper,否则myLooper返回的是null,会抛出异常 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; } /** * 构造方法,初始化。跟2个参数的构造方法的区别是,这儿直接给定了looper */ public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; } /** * 获取trace文件的名字,ANR分析的时候有用 */ public String getTraceName(Message message) { final StringBuilder sb = new StringBuilder(); sb.append(getClass().getName()).append(": "); if (message.callback != null) { sb.append(message.callback.getClass().getName()); } else { sb.append("#").append(message.what); } return sb.toString(); } /** * 获取消息的名称,用消息的callback类名或者what的十六进制命名 * * @param message The message whose name is being queried */ public String getMessageName(Message message) { if (message.callback != null) { //如果规定了message的回调,返回该回调类的名字 return message.callback.getClass().getName(); } //如果message没有指定回调,返回what的十六进制 return "0x" + Integer.toHexString(message.what); } /** * 从消息池中获取一个回收的message对象返回, * 但是这个message的处理handler是调用该方法的handler * 这样效率比直接new一个Message要好 * 如果不想处理消息的handler被指定为调用的handler可以调用Message.obtain方法 */ public final Message obtainMessage() { return Message.obtain(this); } /** * 跟上面的方法差不多,只是多了一点,指定了message的what变量值 */ public final Message obtainMessage(int what) { return Message.obtain(this, what); } public final Message obtainMessage(int what, Object obj) { return Message.obtain(this, what, obj); } public final Message obtainMessage(int what, int arg1, int arg2) { return Message.obtain(this, what, arg1, arg2); } public final Message obtainMessage(int what, int arg1, int arg2, Object obj) { return Message.obtain(this, what, arg1, arg2, obj); } /** * 将一个Runnable放到消息队列中,处理的时候是由当前handler依附的线程处理 */ public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } /** * 跟上面的方法一样,只是多了一个执行的时间指定,会在(uptimeMillis)这段时间过后才执行 */ public final boolean postAtTime(Runnable r, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r), uptimeMillis); } public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); } public final boolean postDelayed(Runnable r, long delayMillis) { return sendMessageDelayed(getPostMessage(r), delayMillis); } public final boolean postAtFrontOfQueue(Runnable r) { return sendMessageAtFrontOfQueue(getPostMessage(r)); } public final boolean runWithScissors(final Runnable r, long timeout) { if (r == null) { throw new IllegalArgumentException("runnable must not be null"); } if (timeout < 0) { throw new IllegalArgumentException("timeout must be non-negative"); } if (Looper.myLooper() == mLooper) { r.run(); return true; } BlockingRunnable br = new BlockingRunnable(r); return br.postAndWait(this, timeout); } /** * 移除消息队列中所有待处理的任务 */ public final void removeCallbacks(Runnable r) { mQueue.removeMessages(this, r, null); } /** * Remove any pending posts of Runnable <var>r</var> with Object * <var>token</var> that are in the message queue. If <var>token</var> is null, * all callbacks will be removed. */ public final void removeCallbacks(Runnable r, Object token) { mQueue.removeMessages(this, r, token); } /** * 将消息push到消息队列的队尾,轮到处理该消息的时候会回调handleMessage去处理 * 如果push成功返回true,如果这个消息队列已经exiting,将会push失败,返回false */ public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); } /** * 将一个没有携带数据,只有what值的空消息push到消息队列中 */ public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0); } /** * 将一个没有携带数据,只有what值的空消息push到消息队列中,但是会在特定的时间过后才能被delivered */ public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); } public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); } /** * 将一个消息放入队列,在当前时间+delayMillis(比如:一个小时之后处理,现在是12点,那就是12:00+1*60*60*1000) * 时间点之前应该要处理的消息全部处理完了之后,会在当前handler依附的线程中处理该消息。 * 这个消息将被传到handleMessage方法中 */ public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } /** * 将一个消息放入消息队列,在uptimeMillis(比如13:00)这个绝对时间点之前应该处理的消息处理完成之后会处理该消息 */ public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); } /** * 讲一个消息放在队首,这个方法一般不会使用,需要在特定的情况下使用。因为这个方法可能会导致 * 消息队列的排序出现问题,或者一些无法想象的异常出现 */ public final boolean sendMessageAtFrontOfQueue(Message msg) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, 0); } /** * 将消息放入队列中,在uptimeMillis(13:00)处理这个消息 * * @param queue 将消息放入这个消息队列 * @param msg 想要处理的消息 * @param uptimeMillis 处理的绝对时间点 * @return */ private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { //指定处理该消息的handler为当前调用的handler msg.target = this; if (mAsynchronous) { //将消息设置为可异步 msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); } /** * 从消息队列中移除指定what值的,未处理的消息.移除之后这些消息对象会被回收,将不会被取出执行 */ public final void removeMessages(int what) { mQueue.removeMessages(this, what, null); } /** * 从消息队列中移除指定what,和obj值,并且未处理的消息,移除之后这些消息对象会被回收,将不会被取出执行 */ public final void removeMessages(int what, Object object) { mQueue.removeMessages(this, what, object); } /** * 从消息队列中移除所有指定obj值,并且未处理的消息和任务,移除之后这些消息对象会被回收,将不会被取出执行 */ public final void removeCallbacksAndMessages(Object token) { mQueue.removeCallbacksAndMessages(this, token); } /** * 查询消息队列中是否有跟指定what值的消息 */ public final boolean hasMessages(int what) { return mQueue.hasMessages(this, what, null); } /** * Check if there are any pending posts of messages with code ‘what‘ and * whose obj is ‘object‘ in the message queue. */ public final boolean hasMessages(int what, Object object) { return mQueue.hasMessages(this, what, object); } /** * 查询消息队列中是否有指定任务 */ public final boolean hasCallbacks(Runnable r) { return mQueue.hasMessages(this, r, null); } // if we can get rid of this method, the handler need not remember its loop // we could instead export a getMessageQueue() method... public final Looper getLooper() { return mLooper; } public final void dump(Printer pw, String prefix) { pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); if (mLooper == null) { pw.println(prefix + "looper uninitialized"); } else { mLooper.dump(pw, prefix + " "); } } @Override public String toString() { return "Handler (" + getClass().getName() + ") {" + Integer.toHexString(System.identityHashCode(this)) + "}"; } ...... }
public final class Message implements Parcelable { /** * 用于指定当前消息的身份 */ public int what; /** * 该消息所携带的简单数据 */ public int arg1; /** * 消息所携带的简单数据 */ public int arg2; /** * 一个Object类型的数据,这个数据可以用于进程间数据传递,这儿不深究 */ public Object obj; /** * Optional Messenger where replies to this message can be sent. The * semantics of exactly how this is used are up to the sender and * receiver. */ public Messenger replyTo; /** * 通过 {@link Messenger}进行进程间数据传递的时候才会有效,代表发送消息的进程的UID,一般情况下为-1,这儿同样不进行深究; */ public int sendingUid = -1; /** * 用于标志当前消息是否正在使用 */ /*package*/ static final int FLAG_IN_USE = 1 << 0; /** * 用于标志当前消息的同步和异步 */ /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1; /** * Flags to clear in the copyFrom method */ /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE; /*package*/ int flags; /*package*/ long when; /*package*/ Bundle data; /** * 处理该消息的handler */ /*package*/ Handler target; /** * 处理消息的回调,如果没有这个回调将会调用Handler的handleMessage方法进行处理 */ /*package*/ Runnable callback; /** * 保存了下一个message对象的地址 */ /*package*/ Message next; private static final Object sPoolSync = new Object(); private static Message sPool; private static int sPoolSize = 0; private static final int MAX_POOL_SIZE = 50; private static boolean gCheckRecycle = true; /** * 从消息池中获取一个message对象返回,避免过多创建对象 */ public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); } /** * 从消息池中获取一个message对象返回,避免过多创建对象 * 并且将传进来的消息中的数据复制给message,并返回 */ public static Message obtain(Message orig) { Message m = obtain(); m.what = orig.what; m.arg1 = orig.arg1; m.arg2 = orig.arg2; m.obj = orig.obj; m.replyTo = orig.replyTo; m.sendingUid = orig.sendingUid; if (orig.data != null) { m.data = new Bundle(orig.data); } m.target = orig.target; m.callback = orig.callback; return m; } /** * 从消息池中获取一个message对象返回,避免过多创建对象 * 指定一个handler去处理 */ public static Message obtain(Handler h) { Message m = obtain(); m.target = h; return m; } /** * 从消息池中获取一个message对象返回,避免过多创建对象 * 指定一个handler去处理 * 并指定处理的回调接口 */ public static Message obtain(Handler h, Runnable callback) { Message m = obtain(); m.target = h; m.callback = callback; return m; } /** * Same as {@link #obtain()}, but sets the values for both <em>target</em> and * <em>what</em> members on the Message. * * @param h Value to assign to the <em>target</em> member. * @param what Value to assign to the <em>what</em> member. * @return A Message object from the global pool. */ public static Message obtain(Handler h, int what) { Message m = obtain(); m.target = h; m.what = what; return m; } /** * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em> * members. * * @param h The <em>target</em> value to set. * @param what The <em>what</em> value to set. * @param obj The <em>object</em> method to set. * @return A Message object from the global pool. */ public static Message obtain(Handler h, int what, Object obj) { Message m = obtain(); m.target = h; m.what = what; m.obj = obj; return m; } /** * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, * <em>arg1</em>, and <em>arg2</em> members. * * @param h The <em>target</em> value to set. * @param what The <em>what</em> value to set. * @param arg1 The <em>arg1</em> value to set. * @param arg2 The <em>arg2</em> value to set. * @return A Message object from the global pool. */ public static Message obtain(Handler h, int what, int arg1, int arg2) { Message m = obtain(); m.target = h; m.what = what; m.arg1 = arg1; m.arg2 = arg2; return m; } /** * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members. * * @param h The <em>target</em> value to set. * @param what The <em>what</em> value to set. * @param arg1 The <em>arg1</em> value to set. * @param arg2 The <em>arg2</em> value to set. * @param obj The <em>obj</em> value to set. * @return A Message object from the global pool. */ public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj) { Message m = obtain(); m.target = h; m.what = what; m.arg1 = arg1; m.arg2 = arg2; m.obj = obj; return m; } /** * @hide */ public static void updateCheckRecycle(int targetSdkVersion) { if (targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) { gCheckRecycle = false; } } /** * 回收message,先检查当前消息是否正在使用,如果正在使用抛出异常 * 如果没有使用就会回收掉,回收之后将不能再使用这个消息 */ public void recycle() { if (isInUse()) { if (gCheckRecycle) { throw new IllegalStateException("This message cannot be recycled because it " + "is still in use."); } return; } recycleUnchecked(); } /** * 内部调用回收message,不会检查当前消息是否正在使用,直接回收,回收之后将不能再使用这个消息 */ void recycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } } /** * 复制o的数据(不包括队列相关的数据)给当前消息 */ public void copyFrom(Message o) { this.flags = o.flags & ~FLAGS_TO_CLEAR_ON_COPY_FROM; this.what = o.what; this.arg1 = o.arg1; this.arg2 = o.arg2; this.obj = o.obj; this.replyTo = o.replyTo; this.sendingUid = o.sendingUid; if (o.data != null) { this.data = (Bundle) o.data.clone(); } else { this.data = null; } } /** * 返回消息的处理时间 */ public long getWhen() { return when; } /* *指定处理该消息的handler */ public void setTarget(Handler target) { this.target = target; } /** * 获取将处理该消息的handler */ public Handler getTarget() { return target; } /** * 处理消息的回调,如果没有设置这个回调,调用handler的handleMessage方法进行处理 */ public Runnable getCallback() { return callback; } /** * 获取Bundle类型的data数据,这个数据是通过setData方法传递进来的 * 其实这个方法中的数据可用于进程间数据传递,这儿我们不深究 * * @see #peekData() * @see #setData(Bundle) */ public Bundle getData() { if (data == null) { data = new Bundle(); } return data; } /** * 跟setData差不多,但是不同的是返回的data可能为null */ public Bundle peekData() { return data; } /** * 给data赋值 */ public void setData(Bundle data) { this.data = data; } /** * 发送一个消息给处理该消息的handler,如果这个handler为null,将会抛出空指针异常 */ public void sendToTarget() { target.sendMessage(this); } /** * 如果返回true,该消息就是异步的,将不会手looper的限制。 * 一般来说我们的消息是受looper的控制是同步的 */ public boolean isAsynchronous() { return (flags & FLAG_ASYNCHRONOUS) != 0; } /** * 对消息的异步进行设置,如果设置为true,消息不会受looper限制,将会是异步的 */ public void setAsynchronous(boolean async) { if (async) { flags |= FLAG_ASYNCHRONOUS; } else { flags &= ~FLAG_ASYNCHRONOUS; } } /** * 当前消息是否正在使用 */ boolean isInUse() { return ((flags & FLAG_IN_USE) == FLAG_IN_USE); } /*package*/ void markInUse() { flags |= FLAG_IN_USE; } /** * 构造器,一般来说不要直接通过构造器创建message,尽量用obtain方法 */ public Message() { }
* 内部维护消息队列,这个消息队列中的消息是按照处理的时间先后顺序排队的 * 跟looper协作进行消息的分发,指派。 * 消息是通过Handler关联上Looper之后,放到消息队列中,然 * 后通过looper取出调用handler的dispatchMessage方法进行处理 */ public final class MessageQueue { private static final String TAG = "MessageQueue"; private static final boolean DEBUG = false; // 代表当前消息队列能否exit private final boolean mQuitAllowed; @SuppressWarnings("unused") private long mPtr; // used by native code Message mMessages; private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private IdleHandler[] mPendingIdleHandlers; // private boolean enqueueMessage; // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout. private boolean mBlocked; // The next barrier token. // Barriers are indicated by messages with a null target whose arg1 field carries the token. private int mNextBarrierToken; private native static long nativeInit(); private native static void nativeDestroy(long ptr); private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/ private native static void nativeWake(long ptr); private native static boolean nativeIsPolling(long ptr); private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); //构造方法,初始化 MessageQueue(boolean quitAllowed) { mQuitAllowed = quitAllowed; mPtr = nativeInit(); } @Override protected void finalize() throws Throwable { try { dispose(); } finally { super.finalize(); } } // Disposes of the underlying message queue. // Must only be called on the looper thread or the finalizer. private void dispose() { if (mPtr != 0) { nativeDestroy(mPtr); mPtr = 0; } } /** * 判断跟这个消息队列关联的looper是不是为空闲状态,true表示空闲,false表示非空闲 */ public boolean isIdle() { synchronized (this) { //获取系统时间 final long now = SystemClock.uptimeMillis(); //如果消息队列中没有消息,或者需要处理的消息里面时间最早的一个都是在当前系统时间的后面,那就代表着空闲 return mMessages == null || now < mMessages.when; } } /** * 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> * <p>This method is safe to call from any thread. * * @param handler The IdleHandler to be added. */ public void addIdleHandler(@NonNull IdleHandler handler) { if (handler == null) { throw new NullPointerException("Can‘t add a null IdleHandler"); } synchronized (this) { 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. * <p> * <p>This method is safe to call from any thread. * * @param handler The IdleHandler to be removed. */ public void removeIdleHandler(@NonNull IdleHandler handler) { synchronized (this) { mIdleHandlers.remove(handler); } } /** * Returns whether this looper‘s thread is currently polling for more work to do. * looper依附的线程正在循环做一些事儿 * This is a good signal that the loop is still alive rather than being stuck * handling a callback. * 这个信号可以表明loop是阻塞状态还是活跃状态 * Note that this method is intrinsically racy, since the * state of the loop can change before you get the result back. * <p> * <p>This method is safe to call from any thread. * * @return True if the looper is currently polling for events. * @hide */ public boolean isPolling() { synchronized (this) { return isPollingLocked(); } } private boolean isPollingLocked() { // If the loop is quitting then it must not be idling. // We can assume mPtr != 0 when mQuitting is false. return !mQuitting && nativeIsPolling(mPtr); } public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd, @OnFileDescriptorEventListener.Events int events, @NonNull OnFileDescriptorEventListener listener) { if (fd == null) { throw new IllegalArgumentException("fd must not be null"); } if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } synchronized (this) { updateOnFileDescriptorEventListenerLocked(fd, events, listener); } } public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) { if (fd == null) { throw new IllegalArgumentException("fd must not be null"); } synchronized (this) { updateOnFileDescriptorEventListenerLocked(fd, 0, null); } } private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events, OnFileDescriptorEventListener listener) { final int fdNum = fd.getInt$(); int index = -1; FileDescriptorRecord record = null; if (mFileDescriptorRecords != null) { index = mFileDescriptorRecords.indexOfKey(fdNum); if (index >= 0) { record = mFileDescriptorRecords.valueAt(index); if (record != null && record.mEvents == events) { return; } } } if (events != 0) { events |= OnFileDescriptorEventListener.EVENT_ERROR; if (record == null) { if (mFileDescriptorRecords == null) { mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>(); } record = new FileDescriptorRecord(fd, events, listener); mFileDescriptorRecords.put(fdNum, record); } else { record.mListener = listener; record.mEvents = events; record.mSeq += 1; } nativeSetFileDescriptorEvents(mPtr, fdNum, events); } else if (record != null) { record.mEvents = 0; mFileDescriptorRecords.removeAt(index); } } // Called from native code. private int dispatchEvents(int fd, int events) { // Get the file descriptor record and any state that might change. final FileDescriptorRecord record; final int oldWatchedEvents; final OnFileDescriptorEventListener listener; final int seq; synchronized (this) { record = mFileDescriptorRecords.get(fd); if (record == null) { return 0; // spurious, no listener registered } oldWatchedEvents = record.mEvents; events &= oldWatchedEvents; // filter events based on current watched set if (events == 0) { return oldWatchedEvents; // spurious, watched events changed } listener = record.mListener; seq = record.mSeq; } // Invoke the listener outside of the lock. int newWatchedEvents = listener.onFileDescriptorEvents( record.mDescriptor, events); if (newWatchedEvents != 0) { newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR; } // Update the file descriptor record if the listener changed the set of // events to watch and the listener itself hasn‘t been updated since. if (newWatchedEvents != oldWatchedEvents) { synchronized (this) { int index = mFileDescriptorRecords.indexOfKey(fd); if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record && record.mSeq == seq) { record.mEvents = newWatchedEvents; if (newWatchedEvents == 0) { mFileDescriptorRecords.removeAt(index); } } } } // Return the new set of events to watch for native code to take care of. return newWatchedEvents; } /** * 如果消息队列中还有下一个消息,取出这个消息 * * @return */ Message next() { // Return here if the message loop has already quit and been disposed. // This can happen if the application tries to restart a looper after quit // which is not supported. final long ptr = mPtr; if (ptr == 0) { return null; } int pendingIdleHandlerCount = -1; // -1 only during first iteration //下一次循环的时间,相当于一个闹钟 int nextPollTimeoutMillis = 0; for (; ; ) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null && msg.target == null) { // 跳过消息队列中的异步消息 do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } if (msg != null) { if (now < msg.when) { // 如果第一个消息的处理时间还没到,就设定一个闹钟,等到闹钟响起,再开始处理 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { //获取一个消息对象 mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // 消息对立中没有消息 nextPollTimeoutMillis = -1; } // 所有的消息都处理完之后,退出message if (mQuitting) { dispose(); return null; } // If first time idle, then get the number of idlers to run. // Idle handles only run if the queue is empty or if the first message // in the queue (possibly a barrier) is due to be handled in the future. if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; } if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); } // Run the idle handlers. // We only ever reach this code block during the first iteration. for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler boolean keep = false; try { keep = idler.queueIdle(); } catch (Throwable t) { Log.wtf(TAG, "IdleHandler threw exception", t); } if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } } // Reset the idle handler count to 0 so we do not run them again. pendingIdleHandlerCount = 0; // While calling an idle handler, a new message could have been delivered // so go back and look again for a pending message without waiting. nextPollTimeoutMillis = 0; } } /** * 退出消息队列,在looper退出的时候调用 * * @param safe true表示安全退出,false强行退出 */ void quit(boolean safe) { if (!mQuitAllowed) { throw new IllegalStateException("Main thread not allowed to quit."); } synchronized (this) { if (mQuitting) { return; } mQuitting = true; if (safe) { //安全退出 removeAllFutureMessagesLocked(); } else { //强行退出 removeAllMessagesLocked(); } // We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); } } public int postSyncBarrier() { return postSyncBarrier(SystemClock.uptimeMillis()); } private int postSyncBarrier(long when) { // Enqueue a new sync barrier token. // We don‘t need to wake the queue because the purpose of a barrier is to stall it. synchronized (this) { final int token = mNextBarrierToken++; final Message msg = Message.obtain(); msg.markInUse(); msg.when = when; msg.arg1 = token; Message prev = null; Message p = mMessages; if (when != 0) { while (p != null && p.when <= when) { prev = p; p = p.next; } } if (prev != null) { // invariant: p == prev.next msg.next = p; prev.next = msg; } else { msg.next = p; mMessages = msg; } return token; } } public void removeSyncBarrier(int token) { // Remove a sync barrier token from the queue. // If the queue is no longer stalled by a barrier then wake it. synchronized (this) { Message prev = null; Message p = mMessages; while (p != null && (p.target != null || p.arg1 != token)) { prev = p; p = p.next; } if (p == null) { throw new IllegalStateException("The specified message queue synchronization " + " barrier token has not been posted or has already been removed."); } final boolean needWake; if (prev != null) { prev.next = p.next; needWake = false; } else { mMessages = p.next; needWake = mMessages == null || mMessages.target != null; } p.recycleUnchecked(); // If the loop is quitting then it is already awake. // We can assume mPtr != 0 when mQuitting is false. if (needWake && !mQuitting) { nativeWake(mPtr); } } } boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } synchronized (this) { if (mQuitting) { IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); return false; } msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { //消息队列中还没有消息存在或者当前插入消息的处理时间比队列中存在 // 的所有消息的处理时间都要早,就将该消息放在队首 msg.next = p; mMessages = msg; needWake = mBlocked; } else { /** * 将消息存放到队列的中间位置,根据处理的时机,跟队列中所有消息的处理时间进行比较,按从早到迟的顺序安插 */ needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; //遍历队列,根据该消息的处理时间,将该消息插入到合适的位置 for (; ; ) { prev = p; p = p.next; if (p == null || when < p.when) { //如果已经是队尾或者当前消息的处理时间比下一个消息的处理时间早,跳出循环 break; } if (needWake && p.isAsynchronous()) { needWake = false; } } //将消息入队 msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; } /** * 查询handler相关联的消息队列中,是否有指定what和指定obj的消息 * * @param h 想要查询的关联handler * @param what 消息的what值 * @param object 消息的obj值 * @return */ boolean hasMessages(Handler h, int what, Object object) { if (h == null) { return false; } synchronized (this) { Message p = mMessages; while (p != null) { if (p.target == h && p.what == what && (object == null || p.obj == object)) { return true; } p = p.next; } return false; } } /** * 查询handler相关联的消息队列中,是否有指定obj的任务 * * @param h 想要查询的关联handler * @param object 任务的obj值 * @return */ boolean hasMessages(Handler h, Runnable r, Object object) { if (h == null) { return false; } synchronized (this) { Message p = mMessages; while (p != null) { if (p.target == h && p.callback == r && (object == null || p.obj == object)) { return true; } p = p.next; } return false; } } /** * 移除跟h相关联的消息队列中,指定what值和obj值的消息 * * @param h * @param what * @param object */ void removeMessages(Handler h, int what, Object object) { if (h == null) { return; } synchronized (this) { Message p = mMessages; // Remove all messages at front. while (p != null && p.target == h && p.what == what && (object == null || p.obj == object)) { Message n = p.next; mMessages = n; p.recycleUnchecked(); 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)) { Message nn = n.next; n.recycleUnchecked(); p.next = nn; continue; } } p = n; } } } /** * 移除跟h相关联的消息队列中,指定obj值的任务 * * @param h * @param r * @param object */ void removeMessages(Handler h, Runnable r, Object object) { if (h == null || 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.recycleUnchecked(); 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.recycleUnchecked(); p.next = nn; continue; } } p = n; } } } /** * 移除跟指定handler相关联的消息队列中,指定obj值的所有消息 * * @param h * @param object */ void removeCallbacksAndMessages(Handler h, Object object) { if (h == null) { return; } 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.recycleUnchecked(); 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.recycleUnchecked(); p.next = nn; continue; } } p = n; } } } //回收消息队列中所有的消息 private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { Message n = p.next; p.recycleUnchecked(); p = n; } mMessages = null; } /** * 安全退出消息队列 */ private void removeAllFutureMessagesLocked() { final long now = SystemClock.uptimeMillis(); Message p = mMessages; if (p != null) { if (p.when > now) { //如果在消息设定的处理时间还没到,直接回收掉,将不会处理 removeAllMessagesLocked(); } else { Message n; for (; ; ) { n = p.next; if (n == null) { return; } if (n.when > now) { break; } p = n; } p.next = null; do { p = n; n = p.next; p.recycleUnchecked(); } while (n != null); } } } void dump(Printer pw, String prefix) { synchronized (this) { long now = SystemClock.uptimeMillis(); int n = 0; for (Message msg = mMessages; msg != null; msg = msg.next) { pw.println(prefix + "Message " + n + ": " + msg.toString(now)); n++; } pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked() + ", quitting=" + mQuitting + ")"); } } ...... }
public final class Looper { private static final String TAG = "Looper"; /* ThreadLocal保存了线程所有的变量,可以通过get方法去获取对应的变量,取得的变量是什么取决于泛型, 这儿传的是Looper,所以获取的是线程的Looper变量,在prepare方法中会创建一个looper存在sThreadLocal中, 如果没有先prepare,sThreadLocal.get取得的就是null*/ static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; final Thread mThread; private Printer mLogging; private long mTraceTag; /** * 初始化一个looper给当前线程 */ public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { //先查询sThreadLocal,如果已经存在looper会抛出异常 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } //创建一个looper对象存放到sThreadLocal中 sThreadLocal.set(new Looper(quitAllowed)); } /** * 为UI线程准备的,系统初始化UI线程的时候调用。我们一般不需要调用这个方法 */ public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } /** * 获取UI线程中的looper变量 */ public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } } /** * 从MessageQueue中取出Message,调用Handler中的dispatchMessage,对消息进行处理 */ public static void loop() { //获取到looper,如果没有之前prepare,取到的会是null,抛出异常 final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread."); } //取出消息中的消息队里MessageQueue final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. /** * 确认当前线程的身份是属于当前本地进程,确保track是属于这个线程 */ Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); //一个死循环,一直处理消息队里中的消息,直到所有的消息处理完成才会退出 for (; ; ) { //获取下一个消息,有可能阻塞 Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger final Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } final long traceTag = me.mTraceTag; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { //开始记录trace,在ANR分析中会用到trace.txt文件 Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } try { //调用handler的方法处理消息 msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { //结束trace记录 Trace.traceEnd(traceTag); } } if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn‘t corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } //回收该消息 msg.recycleUnchecked(); } } /** * R获取当前线程的looper变量 */ public static @Nullable Looper myLooper() { return sThreadLocal.get(); } /** * Return the {@link MessageQueue} object associated with the current * thread. This must be called from a thread running a Looper, or a * NullPointerException will be thrown. */ public static @NonNull MessageQueue myQueue() { return myLooper().mQueue; } /** * 构造方法私有化,在prepare中调用,初始化。 * * @param quitAllowed */ private Looper(boolean quitAllowed) { //创建一个消息队列,用于存放消息 mQueue = new MessageQueue(quitAllowed); //取得当前线程,让该looper跟当前线程关联 mThread = Thread.currentThread(); } /** * 判断looper是否为当前线程的looper */ public boolean isCurrentThread() { return Thread.currentThread() == mThread; } /** * 记录被该looper对象处理的所有消息的控制标志,如果enabled, * 将会通过Trace.traceBegin和Trace.traceEnd(traceTag)控制记录每一条消息的处理状况; * * @param printer A Printer object that will receive log messages, or * null to disable message logging. */ public void setMessageLogging(@Nullable Printer printer) { mLogging = printer; } /** * {@hide} */ public void setTraceTag(long traceTag) { mTraceTag = traceTag; } /** * 退出当前looper操作 * 在当前looper的消息队列没有消息需要处理的时候才可以调用该方法, * 该方法调用的时候会将所有消息队列中的消息回收, * 在这个方法之后所有的消息将不会再被处理,包括当前正在处理的消息 * 一般来说用quitSafely代替该方法,因为该方法不安全,他不能保证已经被delivered的消息处理完成 */ public void quit() { mQueue.quit(false); } /** * 安全终止looper * 会先将消息的处理时间在当前时间点之前的消息全部处理完之后才会终止looper, * 但是不能保证执行时间是在当前时间之后的消息被处理 */ public void quitSafely() { mQueue.quit(true); } /** * 获取当前looper关联的线程 */ public @NonNull Thread getThread() { return mThread; } /** * 获取当前looper持有的消息队列 */ public @NonNull MessageQueue getQueue() { return mQueue; } /** * Dumps the state of the looper for debugging purposes. * * @param pw A printer to receive the contents of the dump. * @param prefix A prefix to prepend to each line which is printed. */ public void dump(@NonNull Printer pw, @NonNull String prefix) { pw.println(prefix + toString()); mQueue.dump(pw, prefix + " "); } @Override public String toString() { return "Looper (" + mThread.getName() + ", tid " + mThread.getId() + ") {" + Integer.toHexString(System.identityHashCode(this)) + "}"; } }
/** * 构造方法,初始化 */ public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } //获取一个Looper,UI线程系统自动调用prepareMainLooper方法,创建了UI线程的looper //如果Handler在子线程中创建,必须先调用prepare创建一个looper,否则myLooper返回的是null,会抛出异常 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; } /** * 构造方法,初始化。跟2个参数的构造方法的区别是,这儿直接给定了looper */ public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
/** * 构造方法私有化,在prepare中调用,初始化。 * * @param quitAllowed */ private Looper(boolean quitAllowed) { //创建一个消息队列,用于存放消息 mQueue = new MessageQueue(quitAllowed); //取得当前线程,让该looper跟当前线程关联 mThread = Thread.currentThread(); }
/** * 初始化一个looper给当前线程 */ public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { //先查询sThreadLocal,如果已经存在looper会抛出异常 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } //创建一个looper对象存放到sThreadLocal中 sThreadLocal.set(new Looper(quitAllowed)); }
sThreadLocal.set(newLooper(quitAllowed));这句代码是调用构造方法创建了一个Looper实例,并且交给了ThreadLocal保存。这儿我想要说明白的一个点,那就是Looper的创建过程,是通过prepare方法调用构造方法进行初始化的,在初始化的时候,创建了一个MessageQueue实例mQueue,并且获取到了当前线程的实例mThread。通过初始化,让Looper跟当前线程绑定上了,并且还绑定了一个消息队列
/** * 获取当前线程的looper变量 */ public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
public T get() { //获取当前线程的实例 Thread t = Thread.currentThread(); //得到Thread中的ThreadLocalMap实例 ThreadLocalMap map = getMap(t); //遍历Map集合,将Value值返回 if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) //泛型,根据初始化的时候指定的类型返回当前线程的特定变量 return (T)e.value; } //如果集合为null,先创建一个null值代替返回 return setInitialValue(); }
/** * 将消息push到消息队列的队尾,轮到处理该消息的时候会回调handleMessage去处理 * 如果push成功返回true,如果这个消息队列已经exiting,将会push失败,返回false */ public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); } /** * 将一个没有携带数据,只有what值的空消息push到消息队列中 */ public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0); } /** * 将一个没有携带数据,只有what值的空消息push到消息队列中,但是会在特定的时间过后才能被delivered */ public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); } /** * Sends a Message containing only the what value, to be delivered * at a specific time. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. * @see #sendMessageAtTime(android.os.Message, long) */ public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); } /** * 将一个消息放入队列,在当前时间+delayMillis(比如:一个小时之后处理,现在是12点,那就是12:00+1*60*60*1000) * 时间点之前应该要处理的消息全部处理完了之后,会在当前handler依附的线程中处理该消息。 * 这个消息将被传到handleMessage方法中 */ public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } /** * 将一个消息放入消息队列,在uptimeMillis(比如13:00)这个绝对时间点之前应该处理的消息处理完成之后会处理该消息 */ public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); }
/** * 将消息放入队列中,在uptimeMillis(13:00)处理这个消息 * * @param queue 将消息放入这个消息队列 * @param msg 想要处理的消息 * @param uptimeMillis 处理的绝对时间点 * @return */ private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { //指定处理该消息的handler为当前调用的handler msg.target = this; if (mAsynchronous) { //将消息设置为可异步 msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } synchronized (this) { if (mQuitting) { IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); return false; } msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { //消息队列中还没有消息存在或者当前插入消息的处理时间比队列中存在 // 的所有消息的处理时间都要早,就将该消息放在队首 msg.next = p; mMessages = msg; needWake = mBlocked; } else { /** * 将消息存放到队列的中间位置,根据处理的时机,跟队列中所有消息的处理时间进行比较,按从早到迟的顺序安插 */ needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; //遍历队列,根据该消息的处理时间,将该消息插入到合适的位置 for (; ; ) { prev = p; p = p.next; if (p == null || when < p.when) { //如果已经是队尾或者当前消息的处理时间比下一个消息的处理时间早,跳出循环 break; } if (needWake && p.isAsynchronous()) { needWake = false; } } //将消息入队 msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
/** * 从MessageQueue中取出Message,调用Handler中的dispatchMessage,对消息进行处理 */ public static void loop() { //获取到looper,如果没有之前prepare,取到的会是null,抛出异常 final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread."); } //取出消息中的消息队里MessageQueue final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. /** * 确认当前线程的身份是属于当前本地进程,确保track是属于这个线程 */ Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); //一个死循环,一直处理消息队里中的消息,直到所有的消息处理完成才会退出 for (; ; ) { //获取下一个消息,有可能阻塞 Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger final Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } final long traceTag = me.mTraceTag; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { //开始记录trace,在ANR分析中会用到trace.txt文件 Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } try { //调用handler的方法处理消息 msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { //结束trace记录 Trace.traceEnd(traceTag); } } if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn‘t corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } //回收该消息 msg.recycleUnchecked(); } }
/** * 如果消息队列中还有下一个消息,根据消息处理的时机取出这个消息 * * @return */ Message next() { // Return here if the message loop has already quit and been disposed. // This can happen if the application tries to restart a looper after quit // which is not supported. final long ptr = mPtr; if (ptr == 0) { return null; } int pendingIdleHandlerCount = -1; // -1 only during first iteration //下一次循环的时间,相当于一个闹钟 int nextPollTimeoutMillis = 0; for (; ; ) { if (nextPollTimeoutMillis != 0) { //如果执行的时间不是现在,通过Binder消息机制通知系统执行一条延迟的命令 Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null && msg.target == null) { // 跳过消息队列中的异步消息 do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } if (msg != null) { if (now < msg.when) { // 计算下一次循环的时机,如果消息处理的时间是现在,计算出来的结果就是0,就不会阻塞 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { //获取一个消息对象 mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // 消息对立中没有消息,将下一次执行循环的时间定为-1,进入阻塞状态 nextPollTimeoutMillis = -1; } // 所有的消息都处理完之后,退出message if (mQuitting) { dispose(); return null; } // If first time idle, then get the number of idlers to run. // Idle handles only run if the queue is empty or if the first message // in the queue (possibly a barrier) is due to be handled in the future. if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; } if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); } // Run the idle handlers. // We only ever reach this code block during the first iteration. for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler boolean keep = false; try { keep = idler.queueIdle(); } catch (Throwable t) { Log.wtf(TAG, "IdleHandler threw exception", t); } if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } } // Reset the idle handler count to 0 so we do not run them again. pendingIdleHandlerCount = 0; // While calling an idle handler, a new message could have been delivered // so go back and look again for a pending message without waiting. nextPollTimeoutMillis = 0; } }
/** * 处理系统消息 * Handle system messages here. */ public void dispatchMessage(Message msg) { //如果msg有回调就交给msg处理 if (msg.callback != null) { handleCallback(msg); } else { //msg没有回调,创建Handler的时候有给回调就交给这个回调处理 if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } //调用自己的handleMessage方法处理,什么也没做,交给子类去具体实现,具体操作。平时我们用的匿名内部类的方式就是走了这一步 handleMessage(msg); } }
Android消息机制之Handler,MessageQueue,Looper源码剖析
原文:http://blog.csdn.net/qq_24692041/article/details/68066025