android-重新理解Handler

前言

Handler想必做android的都知道,我也曾经写过一篇对Handler源码的理解,过了这么一段时间回头看之前写的东西,发现还是很多狭隘之处。并且Handler确实是一个很重要并且有一定深度的知识,所以在这里重新记录下现在的理解。

引言

Android中UI绘制方法大多是非线程按安全的,为了避免多线程下更新UI,造成UI绘制或显示异常,android为我们提供了Handler机制。Handler可以将子线程中的UI操作切换到主线程中执行,保证UI安全。在使用的过程中我们只关注Handler,但Handler机制的实现还需要Looper、Message和MessageQueue的协助,有这四个类才能构成android消息机制。

要想在线程中使用Looper,必须为每一个线程分配单独分配Looper。 为了让创建的Looper只能本线程访问,将每一个创建的Looper保存在ThreadLocal中。Looper的创建会同时创建对应的MessageQueue,MessageQueue是一个保存Message的容器,Message有指向下一个Message的指针,所以构成了单向链表结构的MessageQueue。同时Message有指向发送消息的Handler引用,Handler在子线程中往MessageQueue中存Message(Handler发送消息);Looper一直循环MessageQueue得到Message然后将Message发送到对应的引用(Handler)处理。这基本上构成Handler的基本模型,后面根据源码说明对象间关联的关键代码

Handler的学习不仅要知道其整个消息扭转逻辑。保存Looper的ThreadLocal,Looper的循环中用到的生成消费模型思想,以及在MessageQueue中native层用于阻塞与唤醒的epoll+pipe机制都是可展开学习的。下面就我了解记录如下,如有纰漏请多指点。

关键源码

关于在主线程中使用Handler,还得从Looper的创建开始。在Android中主线程中Looper的创建是在App启动的时候在ActivityThread就已经创建,ActivityThread就是我们所说的主线程,我们先看下ActivityThread的main()方法,下面是android8.0.0ActivityThread的部分代码,

ActivityThread

在 main()方法中先

  • 调用main线程特有的prepareMainLooper()创建一个MainLooper
  • 调用Looper.loop() 开启循环
	public final class ActivityThread {
	...
	 public static void main(String[] args) {
        ...
        //1、创建一个MainLooper,
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        //2、开启循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
	...
	}

上面2步中我们看到了主线程主动创建Looper和开启Looper循环,这就是为什么我们不需要自己在线程中创建Looper,Looper循环在后面我们知道,这是一个死循环,那么这样的设计是否有问题?为此后面会讲到MessageQueue的阻塞和唤醒

Looper

在ActivityThread中主要调用Looper.prepareMainLooper(); Looper.loop();两个方法我们看看相关操作

  1. 主要是创建一个Looper,传入false是控制MessaeQueue能否退出,主线程的MessaeQueue是不能退出
  2. 验证Looper是否已经创建,创建后如果重复调用prepare会报错每一个线程只能创建一个Looper
  3. 使用ThreadLocal保存Looper,后面好取出,能保证每一个线程都只能操作其自己的Looper,别的线程不能访问
  4. Looper的创建伴随着MessageQueue的创建

对于Looper.loop()方法就是开启循环MessageQueue,取出消息

  1. 获取当前Looper并验证是否为空

  2. 获取Looper中的MessageQueue对象

  3. 开始无限循环

  4. 调用MessageQueue的next()方法获取Message,并为Message判空,没有值就return

  5. next()返回 msg不为空,获取到msg的引用target调用其dispatchMessage(msg)方法,可以看出target就是发送消息的handler

  6. 发送消息后将消息回收

	public final class Looper{

    private static final String TAG = "Looper";

    // sThreadLocal.get() will return null unless you've called prepare().
    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;

    /**
     * If set, the looper will show a warning log if a message dispatch takes longer than this.
     */
    private long mSlowDispatchThresholdMs;

    /**
     * If set, the looper will show a warning log if a message delivery (actual delivery time -
     * post time) takes longer than this.
     */
    private long mSlowDeliveryThresholdMs;

    /** Initialize the current thread as a looper.
      * This gives you a chance to create handlers that then reference
      * this looper, before actually starting the loop. Be sure to call
      * {@link #loop()} after calling this method, and end it by calling
      * {@link #quit()}.
      */
    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
    //2 如果重复调用prepareh会报错,每一个线程只能创建一个Looper
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        //3 使用ThreadLocal保存Looper,后面好取出,ThreadLocal能保证每一个线程都只能操作其自己的Looper,别的线程不能访问
        sThreadLocal.set(new Looper(quitAllowed));
    }

    /**
     * Initialize the current thread as a looper, marking it as an
     * application's main looper. The main looper for your application
     * is created by the Android environment, so you should never need
     * to call this function yourself.  See also: {@link #prepare()}
     */
    public static void prepareMainLooper() {
    //1 主要是创建一个Looper,false是控制MessaeQueue能否退出,主线程的MessaeQueue是不能退出,
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

    /**
     * Returns the application's main looper, which lives in the main thread of the application.
     */
    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }
    /**
     * Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */
    public static void loop() {
        //1 获取当前Looper并验证是否为空
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        //2 获取Looper中的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.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        // Allow overriding a threshold with a system prop. e.g.
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        final int thresholdOverride =
                SystemProperties.getInt("log.looper."
                        + Process.myUid() + "."
                        + Thread.currentThread().getName()
                        + ".slow", 0);

        boolean slowDeliveryDetected = false;
		//3 开始无限循环
        for (;;) {
        //4 调用MessageQueue的next()方法获取Message,并为Message判空,没有值就return
            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;
            long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
            long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;
            if (thresholdOverride > 0) {
                slowDispatchThresholdMs = thresholdOverride;
                slowDeliveryThresholdMs = thresholdOverride;
            }
            final boolean logSlowDelivery = (slowDeliveryThresholdMs > 0) && (msg.when > 0);
            final boolean logSlowDispatch = (slowDispatchThresholdMs > 0);

            final boolean needStartTime = logSlowDelivery || logSlowDispatch;
            final boolean needEndTime = logSlowDispatch;

            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }

            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
            final long dispatchEnd;
            try {
            //5 msg不为空,获取到msg的引用target调用其dispatchMessage(msg)方法,可以看出target就是发送消息的handler
                msg.target.dispatchMessage(msg);
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            if (logSlowDelivery) {
                if (slowDeliveryDetected) {
                    if ((dispatchStart - msg.when) <= 10) {
                        Slog.w(TAG, "Drained");
                        slowDeliveryDetected = false;
                    }
                } else {
                    if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
                            msg)) {
                        // Once we write a slow delivery log, suppress until the queue drains.
                        slowDeliveryDetected = true;
                    }
                }
            }
            if (logSlowDispatch) {
                showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", msg);
            }

            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);
            }
			//6 发送消息后将消息回收
            msg.recycleUnchecked();
        }
    }
    ...
	 //4 Looper的创建伴随着MessageQueue的创建   
	 private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
    ...

	}

Message

在上面我们已经看到了MessageQueue的使用,在介绍MessageQueue之前先介绍下MessageQueue中保存的对象Message

Message对于MessageQueue来说,就有如HashMap的Node对象,其构成了MessageQueue的单向链表

  1. 每一个Message对象都有指向下一个Message的引用,自己new的Message会在MessageQueue的enqueueMessage()方法中为其添加next节点
  2. 在获取和创建Message的时候,建议使用Message的obtain()方法,这是Message使用到的缓存池,最大缓存池大小为50,在缓存池没满的情况下避免手动创建Message
  3. Message中有一个发送Message的Handler引用
	public final class Message implements Parcelable {
    /**
     * User-defined message code so that the recipient can identify
     * what this message is about. Each {@link Handler} has its own name-space
     * for message codes, so you do not need to worry about yours conflicting
     * with other handlers.
     */
    public int what;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg1;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg2;

    /**
     * An arbitrary object to send to the recipient.  When using
     * {@link Messenger} to send the message across processes this can only
     * be non-null if it contains a Parcelable of a framework class (not one
     * implemented by the application).   For other data transfer use
     * {@link #setData}.
     *
     * <p>Note that Parcelable objects here are not supported prior to
     * the {@link android.os.Build.VERSION_CODES#FROYO} release.
     */
    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;

    /**
     * Optional field indicating the uid that sent the message.  This is
     * only valid for messages posted by a {@link Messenger}; otherwise,
     * it will be -1.
     */
    public int sendingUid = -1;

    /** If set message is in use.
     * This flag is set when the message is enqueued and remains set while it
     * is delivered and afterwards when it is recycled.  The flag is only cleared
     * when a new message is created or obtained since that is the only time that
     * applications are allowed to modify the contents of the message.
     *
     * It is an error to attempt to enqueue or recycle a message that is already in use.
     */
    /*package*/ static final int FLAG_IN_USE = 1 << 0;

    /** If set message is asynchronous */
    /*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;

    /*package*/ Handler target;

    /*package*/ Runnable callback;

    // sometimes we store linked lists of these things
    /*package*/ Message next;


    /** @hide */
    public 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;

    /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    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();
    }

...
}

MessageQueue

对于MessageQueue主要看添加Message方法enqueueMessage(Message msg, long when)添加同步屏障postSyncBarrier(long when) ,以及循环next()方法 ;以及native方法nativePollOnce(ptr, nextPollTimeoutMillis)nativeWake(mPtr);也是学习的关键

Handler中的Message可以分为两类:同步消息、异步消息。消息类型可以通过以下函数得知

	public boolean isAsynchronous() {
    return (flags & FLAG_ASYNCHRONOUS) != 0;
}

一般情况下这两种消息的处理方式没什么区别,只有在设置了同步屏障时才会出现差异。设置同步屏障的方法就是postSyncBarrier(long when),设置同步屏障后在next() 方法中循环的时候就优先处理异步消息,这样对于消息的处理就形成异步消息优先级>同步消息,这样在处理一些事件时就可以优先处理,如Android应用框架中为了更快的响应UI刷新事件在ViewRootImpl.scheduleTraversals中使用了同步屏障,详细参考博客[13]

这里提前要说一下next()方法中nextPollTimeoutMillis的值所代表的含义,nextPollTimeoutMillis是毫秒时间。
1.如果nextPollTimeoutMillis=-1,一直阻塞不会超时。
2.如果nextPollTimeoutMillis=0,不会阻塞,立即返回。
3.如果nextPollTimeoutMillis>0,最长阻塞nextPollTimeoutMillis毫秒(超时),如果期间有程序唤醒会立即返回。
具体分析看下面源码中注释

	public final class MessageQueue {
    private static final String TAG = "MessageQueue";
    private static final boolean DEBUG = false;

    // True if the message queue can be quit.
    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 mQuitting;

    // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
    //指示是否阻止Next()在PollOnce()中以非零超时等待。
    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;
        //1 通过native方法初始化消息队列,mPtr记录native消息队列的信息
        mPtr = nativeInit();
    }

	...
    Message next() {

        final long ptr = mPtr;
        if (ptr == 0) {
        //2 在dispose()方法中设置mPtr=0,表示循环退出
            return null;
        }

        int pendingIdleHandlerCount = -1; // -1 only during first iteration
        int nextPollTimeoutMillis = 0;
        for (;;) {
            if (nextPollTimeoutMillis != 0) {
                Binder.flushPendingCommands();
            }
		//3 这里会根据nextPollTimeoutMillis进行阻塞操作,当等待nextPollTimeoutMillis超时,或者消息队列被唤醒,都会返回
            nativePollOnce(ptr, nextPollTimeoutMillis);

            synchronized (this) {
           //返回自启动后的毫秒数,不计算在深度睡眠中花费的时间
                final long now = SystemClock.uptimeMillis();
                Message prevMsg = null;
                Message msg = mMessages;
                //碰到同步屏障
                if (msg != null && msg.target == null) {
                    do {
                     //4 跳出循环时,msg指向离表头最近的一个异步消息
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null && !msg.isAsynchronous());
                }
                if (msg != null) {
                    if (now < msg.when) {
          
                     //6 下一条消息尚未准备好。设置超时以在准备就绪时唤醒。
                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                    } else {
                     
                        // 7 获取一条消息,并返回
                        mBlocked = false;
                        if (prevMsg != null) {
                        //将msg从消息链表中移除
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                        msg.markInUse();
                        //返回消息
                        return msg;
                    }
                } else {
                 
                    //8 没有更多的消息,就进行阻塞
                    nextPollTimeoutMillis = -1;
                }
                //9 消息正在退出,返回null
                if (mQuitting) {
                    dispose();
                    return null;
                }

                 // 10 当消息队列为空,或者是消息队列的第一个消息时
                if (pendingIdleHandlerCount < 0
                        && (mMessages == null || now < mMessages.when)) {
                    pendingIdleHandlerCount = mIdleHandlers.size();
                }
                if (pendingIdleHandlerCount <= 0) {
              
                     // 11 没有idle handlers 需要运行,则循环并等待。
                    mBlocked = true;
                    continue;
                }

                if (mPendingIdleHandlers == null) {
                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
                }
                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
            }

    
            //12 只有第一次循环时,会运行idle handlers,执行完成后,重置pendingIdleHandlerCount为0.
            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);
                    }
                }
            }
            //13 重置idle handler个数为0,以保证不会再次重复运行
            pendingIdleHandlerCount = 0;

          //14 调用空闲处理程序时,可能已传递新消息,因此无需等待可以直接查询pending message.
         
            nextPollTimeoutMillis = 0;
        }
    }
	
	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;
        }
    }    

    ...
    
    boolean enqueueMessage(Message msg, long when) {
    	//每一个Message都得有一个Hander 
        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) {
            //正在退出时,回收msg,加入到消息池
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();//回收Message
                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.
                //p为null(代表MessageQueue没有消息) 或者msg的触发时间是队列中最早的, 则进入该该分支
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;//如果被阻塞,唤醒事件队列。
            } else {
                 //将消息按时间顺序插入到MessageQueue。一般地,不需要唤醒事件队列,除非
            //消息队头存在barrier,并且同时Message是队列中最早的异步消息。
                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;
            }
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }
...
}

Handler

handler的主要作用就是对消息的各种操作,如发送消息、延迟发送、删除、获取等操作。要知道Handler就像是一个循环,发出的消息经过MessageQueue和Looper后又回到了Handler中,消息被回转的时候主要是在 loop()方法中调用到Handler的dispatchMessage(msg)方法,然后再具体扭转。

  1. Handler中有一个 Callback 接口,在构造方法中赋值,用于最后回调
  2. 构造方法中在ThreadLocal里获取Looper,如果是主线程获取的就是ActivityThread中创建的Looper
  3. 并得到Looper中的MessageQueue
  4. 在发送消息的时候调用sendMessage后会最后调用到Handler的enqueueMessage方法,在这里为msg设置target,也就是当前Handler引用,并将Message添加到MessageQueue
  5. 在 loop()方法中会调用target.dispatchMessage(msg)方法,这里会判断msg.callback是否为空,不为空就执行message.callback.run()(优先级最高),为空则再判断Handler构造方法里的Callback是否为空,不为空就调用Callback里的handleMessage()(优先级仅次于1),为空则调用Handler的默认handleMessage方法(优先级最低)

到这里就基本明白Handler发送消息的整个流转过程。

	public class Handler {
    /*
     * Set this flag to true to detect anonymous, local or member classes
     * that extend this Handler class and that are not static. These kind
     * of classes can potentially create leaks.
     */
    private static final boolean FIND_POTENTIAL_LEAKS = false;
    private static final String TAG = "Handler";
    private static Handler MAIN_THREAD_HANDLER = null;

    /**
     * Callback interface you can use when instantiating a Handler to avoid
     * having to implement your own subclass of Handler.
     */
    public interface Callback {
        /**
         * @param msg A {@link android.os.Message Message} object
         * @return True if no further handling is desired
         */
        public boolean handleMessage(Message msg);
    }
    
    /**
     * Subclasses must implement this to receive messages.
     */
    public void handleMessage(Message msg) {
    }
    
    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
      	//在 loop()方法中会调用target.dispatchMessage(msg)方法,这里会判断msg.callback是否为空,不为空就执行message.callback.run(),为空则再判断Handler构造方法里的Callback是否为空,为空就调用handleMessage(),不为空则调用接口里面的方法
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

    public Handler() {
        this(null, false);
    }

    
    public Handler(Callback callback) {
        this(callback, false);
    }

  
    public Handler(Looper looper) {
        this(looper, null, false);
    }

   
    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }

   
    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());
            }
        }
	    // 1 在ThreadLocal中获取Looper,如果是主线程获取的就是ActivityThread中创建的Looper
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        //2 并得到Looper中的MessageQueue
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
...

  public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);
    }

   private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
   //3 在调用sendMessage后会最后调用到enqueueMessage方法,在这里为msg设置target,也就是当前Handler引用
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

    private static void handleCallback(Message message) {
        message.callback.run();
    }
...

}

小结

到这里其实已近将Handler机制java层已经讲完了。对于Handler机制其实还有native层的代码,在MessageQueue中就有好几个native方法。在native层,也有一套Handler,native层主要用于处理native的消息。MessageQueue就是java层和native层的纽带,java层可以向MessageQueue添加数据,native层也可以向MessageQueue添加数据。要知道在ActivityThread中是有一套控制Activity生命周期代码的,这些控制生命周期的消息就是从其他进程发送过来,使用native方法进入到MessageQueue,进行循环获取以及执行。

阻塞和唤醒

说MessageQueue带出Epoll机制。有一个问题一直在面试的时候问,主线程为什么在Looper一直循环下而没有卡死?以前我也是不太明白,因为我没有看到MessageQueue中native层的代码,最近回头看的时候发现:在Lopper循环的时候会调用MessageQueue中 nativePollOnce(ptr, nextPollTimeoutMillis)这个native方法,当MessageQueue中没有消息时会进行阻塞,而唤醒主线程则是在 nativeWake(mPtr)方法中
对于具体的native中阻塞和唤醒可以看参考博客[14],对于Epoll机制,就是啊native层实现阻塞与唤醒的关键,是Linux下多路复用IO接口select/poll的增强版本,如果对这一块不懂的可以参考博客[8][9]

我所知道的关于Handler相关的就这么多了,Handler对于安卓还是很重要的,其衍生的HandlerThread,以及在IntentService中的应用都是有Handler的影子,学好Handler再延伸到其他知识点有助于我们理解很多东西。同时感谢文末列出的其他博客

[1]Android的Touch事件是怎么从触摸屏传递到Activity的?
[2]Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
[3]深入理解MessageQueue
[4]从源码角度分析native层消息机制与java层消息机制的关联
[5]进程间的通信方式——pipe
[6]深入理解MessageQueue
[7]android源码在线查看
[8]我读过的最好的epoll讲解–转自”知乎“
[9]Linux IO模式及 select、poll、epoll详解
[10]浅析 Android 输入事件处理(一)
[11]理解Java中的ThreadLocal
[12]Android消息机制2-Handler(Native层)
[13]Handler之同步屏障机制(sync barrier)
[14]Looper中的睡眠等待与唤醒机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值