Handler:用于线程间的通信,handler会在实例化它的Thread上注册,它提供了一个通道将数据发送给它注册的Thread(比如,你在某个activity中onCreate方法中实例化了一个handler,这个handler将用于向主线程中传递数据)通过handler的方法将Message或者Runnable对象发送到handler所在线程的Looper中的MessageQueue中,通过Handler.handMessage()来处理传递过来的Message
Message:handler用于发送和接受的消息对象,里面有一个Bundle用于储存信息对象
MessageQueue:储放消息的阻塞的单向队列,Message会根据遍历比较时间长短(先与first第一个节点的时间比较长短)来排列,等待时间到了再从队列头取出Message(既从头部添加Message,然后按照时间排列,在从头部取出)
Looper:用于循环取出Messagequeue中的Message,每个线程中只能有一个looper对象,每个Looper对象中有一个MessageQueue
- Message 实现了Parcelable接口(表示可以通过intent或bundle在activities或fragments之间传输非基本类型数据对象,也可以通过夸进程传递)
内含的属性变量: public int what //用户定义的消息代码,以便接收方能够识别此消息是关于什么的。(每个handler都有自己的消息空间名称,不必担心与其他handlers冲突。) public int arg1 //arg1和arg2是用于储存简单的整数数字(当用户需要发送的数据时整数时,可以通过arg1和arg2来替代Bundle储存数字) publi cint arg2 //同上 public Object obj //用于在Messenger将Message在进程之间发送时使用 public Messenger replayTo //用于进程之间通信的类 public int sendingUid //用于进程之间通信 static final int FLAG_IN_USE =1<<0 //用于标志Message正在使用的旗帜 static final int FLAG_ASYNCHRONOUS = 1<<1 //用于标志Message在异步操作的旗帜 static final int FLAGS_TO_CLEAR_ON_COPY_FROM =FLAG_IN_USE // int flags // long when // 消息被取出的时间(即延迟操作的延迟时间) Bundle data //用于存放需要传递的数据 Handler target //用于处理该Message的handler Runnable callback //Message的回调接口 Message next //用于消息池中的链式下一个节点 private static final Object sPoolSync = new Object(); //以下属性都是消息池,通过Message.obtain()来获取消息池中的Message,消息池中的Message可以循环使用,大小为50 private static Message sPool private static int sPoolSize; private int MAX_POOL_SIZE = 50 private static boolean gCheckRecycle 主要函数 //从消息池中取出一个空的Message,如果消息池中没有空闲的Message则重新创建一个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的handler为传入的handler public static Message obtain(Handler h) { Message m = obtain(); m.target = h; return m; } //从消息池中取出空的Message,并设置它的handler和callback(Runnable的回调接口) public static Message obtain(Handler h, Runnable callback) { Message m = obtain(); m.target = h; m.callback = callback; return m; } //从消息池中取出空的Message,并设置它的handler和what(消息代码,用于接受者通过switch(message.what)来识别该消息) public static Message obtain(Handler h, int what) { Message m = obtain(); m.target = h; m.what = what; return m; } //用于从消息池中取出一个空的Message,并设置它的handler,what,和arg1,arg2 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; } //属性变量的setter和getter方法 public long getWhen() { return when; } public void setTarget(Handler target) { this.target = target; } public Handler getTarget() { return target; } public Runnable getCallback() { return callback; } public Bundle getData() { if (data == null) { data = new Bundle(); } return data; } public Bundle peekData() { return data; } public void setData(Bundle data) { this.data = data; } //通过它的handler将Message发送到Looper中的MessageQueue中 public void sendToTarget() { target.sendMessage(this); }- Messagequeue
MessageQueue是在Looper内部构造的,通过Looper来调用MessageQueue的函数,MessageQueue是一个单向链表,有一个next字段保存列表中的下一个,mMessages保存链表的第一个元素(表头)
内置属性变量 private final boolean mQuitAllowed ;//MessageQueue是否可以退出 long mPtr;MessageQueue//是通过调用C++native MessageQueue实现的,这个mPtr就是指向nativeMessageQueue的 private boolean mBlocked;//判断MessageQueue是否阻塞 Message mMessages;//当前链表的表头Message int mNextBarrierToken;//表示下一个消息障碍(barrier)的 token,barrier用target==null, arg1==token的Message对象表示;消息屏障是在postSyncBarrier(long when))方法中实现添加的,本质是在MessageQueue中插入一个Message,并且不设置它的target,可以通过removeSyncBarrier(int token)来移除屏障,这两个方法都是私有的,在ViewRootImpl中的scheduleTraversal()方法中会用到,view在绘图之前会插入一个消息屏障,绘制之后移除 ArrayList<IdleHandler> mIdleHandle;//用于保存不紧急的任务hanlder ... 主要函数 //构造MessageQueue MessageQueue(boolean quitAllowed) { mQuitAllowed = quitAllowed; mPtr = nativeInit();//指向底层通过C++写的函数创建的NativeMessageQueue对象 } //将传入的Message插入到MessageQueue中并按照when排列 boolean enqueueMessage(Message msg, long when) { //这里的target为发送和处理msg的handler 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; //插入消息链表的表头,并通过逐个比较Message的触发时间比较 //如果触发时间比现有的头结点mMessages短,或者msg的触发时间为0,亦或者当前消息链表为空时,msg则作为MessgeQueue的头结点,如果阻塞着则立即唤醒线程 if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // 插入msg到链表中部,如果插入消息到链表头部的条件不具备,则依次比较消息触发时间长短,然后将消息插入到消息链表的合适位置 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; } // 当线程需要被唤醒时(插入的消息排列在表头时且线程处于阻塞状态时)调用的是Native层的nativeWake(mptr)方法来唤醒线程 if (needWake) { nativeWake(mPtr); } } return true; } /* MessageQueue.enqueueMessage()的代码逻辑 1.从表头逐个比较按照时间顺序将message插入到消息链表中 2.如果是第一个或者是异步消息则根据mBlocked判断是否需要唤醒线程 */ //取出MessageQueue的下一个Message并在MessageQueue中删除该Message Message next() { //Message.next()是在Looper中looper.loop来死循环调用的,如果looper退出,不能再次启动 final long ptr = mPtr; if (ptr == 0) { return null; } int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0;//nextPollTimeoutMillis的值用于native层线程阻塞时间(-1表示一直阻塞不会超时,0表示不会阻塞立即返回,>0表示最长阻塞nextPollTimeoutMillis毫秒(超时)如果期间有程序唤醒会立即返回))当第一次进入到next循环的时,线程是非阻塞状态 //无限循环 for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } //这是一个Native方法,实际作用时通过native层的MessageQueue阻塞nextPollTimeoutMillis毫秒的时间 nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { // 获得当前的系统时间 final long now = SystemClock.uptimeMillis(); Message prevMsg = null; //将表头赋值给msg(因为处理过的Message都直接从链表中删除了,所以循环每次都是从表头开始) Message msg = mMessages; //判断获取的message是否为消息障碍(消息屏障是在postSyncBarrier(long when))方法中实现添加的,本质是在MessageQueue中插入一个Message,并且不设置它的target,可以通过removeSyncBarrier(int token)来移除屏障,这两个方法都是私有的,在ViewRootImpl中的scheduleTraversal()方法中会用到,view在绘图之前会插入一个消息屏障,绘制之后移除) if (msg != null && msg.target == null) { // 如果发现了一个消息屏障,则会循环找出第一个异步消息(如果有异步消息的话),所有的同步消息都将被忽略(可以通过setAsynchronous(boolean asnc)设置为异步消息) do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } //处理消息 if (msg != null) { if (now < msg.when) { // 先判断消息触发时间有没有到,如果没有到这设置线程阻塞的时间,进入下一个循环,先通过native的nativePollOnce(ptr,nextPollTimeoutMillis)阻塞线程到触发的时间在返回 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { //如果到了触发的时间,则返回该message,并在MessageQueue中删除该message 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 { //如果当前没有消息需要处理,这设置阻塞时间为无限期阻塞(当有Message传入进来时可以返回唤醒(通过enqueueMessage(Message msg.long when)中设置唤醒)) nextPollTimeoutMillis = -1; } // Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); return null; } // 当没有符合条件的message需要被处理时,会处理一些不紧急的任务,然后再次进入到下一次循环中 if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // 没有空闲任务需要处理时,进入到下一次循环 mBlocked = true; continue; } if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); } for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; 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; } } /* MessageQueue.next()的代码逻辑: 1.首次进入循环时nextPollTimeoutMillis = 0,阻塞方法nativePollOnec(ptr,nextPollTimeoutMillis)会立刻返回 2.读取列表中的消息,通过当前时间,是否遇到消息屏障来返回符合条件的待处理消息(如果需要消息屏障,则跳过后面的同步消息,返回符合条件的异步消息) 3.如果没有符合条件的消息,则会处理一些不紧急的任务(idleHandler),再次进入第一步循环,如果消息列表中没有message则设置阻塞时间nextPollTimeoutMillis=-1无限阻塞,进入循环第一步调用native方法进入无限阻塞状态,等待加入新的message时被唤醒 */- Looper
里面有一个MessageQueue,通过looper.loop来循环取出MessageQueue中的Message
内含属性 private static Looper sMainLooper;//Looper对象(Loop的构造器为私有的,只有通过静态方法获得Looper的实例) static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();//通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问(通过sThreadLocal.get(),sThreadLocal.set(E e)来获得和修改该变量的属性值),其他线程则无法访问和修改。 final MessageQUeue mQueue;//Looper中的MessageQueue实例 final Thread mThread;//当前Looper所在的线程 主要函数 //外部通过Looper.prepare()来创建Looper对象 public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { //每个Thread只能创建一个Looper, 如果已经存在一个Looper对象,再通过prepare()来创建则会抛出异常 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } //也是构造Looper sMainLooper,然后通过getMainLooper可以得到Looper的实例 public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } } //返回当前线程中的Looper实例 public static @Nullable Looper myLooper() { return sThreadLocal.get(); } //返回当前Looper实例中的MessageQueue public static @NonNull MessageQueue myQueue() { return myLooper().mQueue; } //私有化的Looper构造器,在构造Looper时也初始化了它的MessageQUeue private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); } //退出该MessaeQueue public void quit() { mQueue.quit(false); } //通过Looper实例获得该Looper所在的线程 public @NonNull Thread getThread() { return mThread; } //返回该Looper实例的消息队列 public @NonNull MessageQueue getQueue() { return mQueue; } //在Looper所在的线程逐个取出并处理Message的方法 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; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // 通过调用MessageQueue的next()方法来逐个取出Message if (msg == null) { // 没有Message(MessageQueue退出了)则直接返回 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 slowDispatchThresholdMs = me.mSlowDispatchThresholdMs; final long traceTag = me.mTraceTag; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); final long end; try { //通过调用handler的dispatchMessage(Message msg)来处理Message msg.target.dispatchMessage(msg); end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } if (slowDispatchThresholdMs > 0) { final long time = end - start; if (time > slowDispatchThresholdMs) { Slog.w(TAG, "Dispatch took " + time + "ms on " + Thread.currentThread().getName() + ", h=" + msg.target + " cb=" + msg.callback + " msg=" + msg.what); } } 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); } //回收Message到消息池中 msg.recycleUnchecked(); } }- Handle
主要属性变量 public static Handler MAIN_THREAD_HANDLER; final Looper mLooper;Handler实例化线程的looper对象 final MessageQueue mQueue;//handler实例化线程的looper中的消息队列 final Callback mCallback;//定义handMessage(Message msg)方法的接口 IMessenger mMessenger;//跨进程通讯使用到的类 主要的函数 //构造方法 public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; } //构造一个Handler实例,并将传入的Looper赋值给实例的mLooper,并传入handleMessage的回调方法 public Handler(Looper looper, Callback callback) { this(looper, callback, false); } //构造一个Handler实例,并将传入的Looper赋值给实例的mLooper public Handler(Looper looper) { this(looper, null, false); } 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()); } } mLooper = Looper.myLooper();//获得实例化所在的线程的ThreadLocal<Looper>通过get()方法得到的Looper对象,如果线程中没有实例化Looper对象,则handler不能接受Message会抛出异常 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; } public Handler(boolean async) { //调用上面的构造方法 this(null, async); } //构造Handle实例,(实例中的Looper是调用的ThreadLocal<Looper>.get()方法得到的,如果该线程中没有实例化Looper对象,则这个handler不能接受信息会抛出异常),并传入handleMessage的回调方法 public Handler(Callback callback) { this(callback, false); } //默认构造器,新建的handler实例中的Looper是调用的ThreadLocal<Looper>.get()方法得到的,如果该线程中没有实例化Looper对象,则这个handler不能接受信息会抛出异常 public Handler() { this(null, false); } //以下handler的post系列方法,将Runnable对象包装成Message的callback再讲message发送到MessageQueue中,最终都是通过sendMessageAtTime(Message msg,long uptimeMillis)方法实现 public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } public final boolean postAtTime(Runnable r, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r), uptimeMillis); } public final boolean postDelayed(Runnable r, long delayMillis) { return sendMessageDelayed(getPostMessage(r), delayMillis); } //handler的send方法,都是通过sendMessageAtTime(Message msg, long uptimeMillis)来实现的 public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); } public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0); } 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); } public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } //post和send方法最终调用的方法 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; } //最终调用MessageQueue的enqueueMessage()方法将Message入队 return enqueueMessage(queue, msg, uptimeMillis); } //handler处理Message的方法,该方法是在Looper中的loop()循环方法中msg.target.dispatchMessage(msg)调用的 public void dispatchMessage(Message msg) { //如果Message的Callback(为Runnable类型)对象不为空,则调用message.callback.run()方法 if (msg.callback != null) { handleCallback(msg); //若handler子类中的Callback对象不为空 } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } private static void handleCallback(Message message) { message.callback.run(); } /* handler.post(Runnable r);//直接传入Runnable对象,(Runnable会在方法内部封装为Message对象,在加入到队列中) handler.sendMessage(Message msg);//直接将Message加入到队列 */消息处理机制的关系图:
消息处理机制的运作步骤:
/*step 1:初始化当前thread中的looper对象(同时也实例化了looper中的messageQueue)*/ Looper.prepare(); /*step 2 : 初始化handler*/ Handler handler = new Handler(); /*step 3:调用Looper.loop()方法,循环取出处理Message*/ Looper.loop(); /*step 4:将消息加入到handler中的Looper对象中的MessageQueue中排列*/ handler.sendMessage(message); /*step 5:处理消息在handleMessage中*/ Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } };tips:
1.主线程中已经初始化了Looper对象
public final class ActivityThread { public static void main(String[] args) { // ... Looper.prepareMainLooper();//初始化了主线程的Looper对象 ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler();//也初始化了一个handler对象 } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop();//将loop中的messageQueue循环处理Message } // ... }获得主线程中的Looper对象可以通过Looper looper = Looper.myLooper(); 获取主线程中已经存在Handler对象Handler= getHandler();
2. 子线程中没有初始化Looper对象需要自己先初始化
new Thread(){ @Override public void run() { Looper.prepare();//初始化Looper Looper.loop();//循环消息队列 Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message message) { //handleMessage的逻辑 return false; } }); } }.start();