Handler工作过程简述
以主线程为例,从APP创建主线程开始,就为主线程创建了一个不可退出的looper,通过getMainLooper()可以获得其对象,以及有了一个looper相对应的队列mQueue,然后主线程中所有的handler,都是通过此唯一的looper进行分发派送消息,所有的msg,也都是依次排列在此唯一的mQueue中,等待looper进行接收分发。由于mQueue中的msg是依次出队的,所以在Activity onCreate()中执行View的post操作可以相应的达到一定的延迟作用。
Looper
Fields
- ThreadLocal<Looper> sThreadLocal:保存当前线程的本地变量,保证一个线程只有looper对象存在;
- Looper sMainLooper:UI线程的looper对象;
- MessageQueue mQueue:当前looper对应的消息队列;
- Thread mThread:记录当前处于的线程对象;
Methods
-
quit()/quitSafely():用于退出当前looper循环(仅仅在子线程中的looper有效,主线程的looper创建之初就不可以退出循环),其内部是调用的mQueue的quit(boolen)方法,mQueue的mQuitAllowed属性记录着当前looper对象是否允许退出循环操作;
public void quit() { mQueue.quit(false); } public void quitSafely() { mQueue.quit(true); }
-
static Looper getMainLooper():获取主线程的looper对象;
-
public static void prepare():子线程中调用,创建子线程的looper(并且允许退出循环);
-
public static @Nullable Looper myLooper():获取当前线程的looper;
-
public static @NonNull MessageQueue myQueue():获取当前线程的消息队列;
-
public @NonNull Thread getThread():获取looper的线程对象;
-
public boolean isCurrentThread():判断当前线程与looper对应的线程是否一致;
-
public static void loop():循环接收消息,通过mQueue.next()来不停获取下一个msg,并根据msg.target进行消息的分发,msg.target是当前handler对象,调用handler.dispatchMessage(msg)将此msg交给handler处理。
MessageQueue
Fields
- private final boolean mQuitAllowed:是否允许looper退出循环;
Methods
-
boolean enqueueMessage(Message msg, long when):将消息压入队列中,判断当前队列中是否有消息,没有则处于队首;或者根据msg.when来确定此msg是否要排在队首,还在插在队列中间某个位置;
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) { // New head, wake up the event queue if blocked. //当前队列没有消息,,直接将msg作为队首 //或者当前队首的时间when大于msg的when时,msg成为新的队首 msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; //遍历队列,根据when来决定msg插入到队列的位置 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; }
-
Message next():返回队列中的下一个msg,其中msg的异步性,也是在此段代码中体现的;
Message next() { ...... 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) { //msg满足上述判断条件后,就会在队列中遍历msg,优先将异步的msg出列, // Stalled by a barrier. Find the next asynchronous message in the queue. do { prevMsg = msg; msg = msg.next; //此循环直到得到异步的msg才会退出循环 } while (msg != null && !msg.isAsynchronous()); } //非异步msg的出列 if (msg != null) { if (now < msg.when) { // Next message is not ready. Set a timeout to wake up when it is ready. nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a 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 { // No more messages. nextPollTimeoutMillis = -1; } ...... } }
-
void quit(boolean safe):提供给looper退出循环的方法(原理:调用此方法后当前队列会返回一个null的msg,looper接收到null的msg后就执行退出循环的操作);
Message
Fields
-
public int what:一般用于区分不同的msg;
-
public int arg1,arg2:传递int数据;
-
public Object obj:传递对象;
-
Handler target:标记此msg需要发送给哪个handler去处理;
-
long when:用于决定其在消息队列中的位置;
-
Runnable callback:handler post方法系列的run回调对象;
-
Bundle data:将数据存储到bundle中进行传递;
-
int flags:用于标记当前msg处于什么状态
- FLAG_IN_USE:msg正在使用中;
- FLAG_ASYNCHRONOUS:异步处理此msg,,在MQueue中会优先让异步的msg出列;
- FLAGS_TO_CLEAR_ON_COPY_FROM:?
-
private static final int MAX_POOL_SIZE = 50;默认消息池的大小为50;
-
public Messenger replyTo:???
-
Message next:用于记录当前msg的下一个msg是哪个,消息队列的实质就是通过此属性,使得所有msg之间形成一个链表的关系,这就是消息队列的存在形式,MessageQueue就是管理这个队列的类(入队,出队,退出等操作)
Methods
- public static Message obtain():消息池中获取一个msg
- public void recycle():回收msg;
Handler
Fields
- final Looper mLooper:要创建一个handler对象,必须要为其设置looper;
- final MessageQueue mQueue:looper对应的消息队列;
- final Callback mCallback:handler处理消息的回调(public boolean handleMessage(Message msg),,通过设置此回调是handler处理msg的方式之一);
Methods
- public final boolean post(Runnable r);
- public final boolean postAtTime(Runnable r, long uptimeMillis);
- public final boolean postDelayed(Runnable r, long delayMillis);
- public final boolean sendMessage(Message msg);
- public boolean sendMessageAtTime(Message msg, long uptimeMillis):handler发送消息最终都会调用到此方法,内部通过私有方法enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis),再通过mQueue.enqueueMessage(msg, uptimeMillis),最终将消息压入到消息队列中。
- public final void removeMessages(int what):将指定的msg移出消息队列(前提是此msg是处于pending等待的状态);
- public final void removeCallbacks(Runnable r):具体使用同6;
- public final void removeCallbacksAndMessages(Object token):当token参数传入null的时候会将消息队列中的所有正在pending的msg全部移除;
- public final Message obtainMessage():从消息池中得到一个空的msg对象(==推荐使用此方式得到msg对象==)
- public void dispatchMessage(Message msg):
在此方法中可以看到,handler处理消息的机制中,msg的callback是优先级最高的,即实现的Runnable接口中的run方法;其次是handler自身的CallBack回调,最后才是自身的handleMessage(msg)方法;/** * * 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); } }
Constructor
- public Handler() ;
- public Handler(Callback callback) :添加处理msg的回调;
- public Handler(Looper looper):添加looper;
- public Handler(Looper looper, Callback callback):
- public Handler(boolean async):此设置此handler发送的msg是否需要异步处理
- public Handler(Callback callback, boolean async) :
- public Handler(Looper looper, Callback callback, boolean async) :
网友评论