Handler,MessageQueue,Message,Looper源码分析

来源:互联网 发布:手机网页小游戏源码 编辑:程序博客网 时间:2024/05/18 02:14
Handler机制源码分析

我的github博客详解


Handler 核心成员变量与方法:


MessageQueue,Message 核心成员变量与方法:


Looper 核心成员变量与方法:


Handler的工作原理涉及:Handler,MessageQueue,Message,Looper,ThreadLocal 等多个类


简单分析:

1,Handler初始化都做些什么?

2,Handler的常用几种方法有哪些?

3,Handler把Meesage发送到什么地方去了?

4,MessageQueue是什么,他与Handler,Message,Looper存在什么样的关系?

5,Message源码分析

6,Handler,Message,MessageQueue,Looper之间是怎么样工作的?

7,子线程也能使用Handler,MessageQueue,Looper机制吗?


开始分析:


1,Handler初始化都做些什么?


先看看Handler的构造函数

        public Handler() {            this(null, false);        }        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();            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(Looper looper, Callback callback, boolean async) {            mLooper = looper;            mQueue = looper.mQueue;            mCallback = callback;            mAsynchronous = async;        }

从上面可以看出,Handler有多个构造器。从代码最多的构造器看到,Handler初始化做了三件事:

1-1,获取到当前线程的Looper

        mLooper = Looper.myLooper();        public static @Nullable Looper myLooper() {            return sThreadLocal.get();        }

1-2,获取当前Looper的消息队列MessageQueue

        mQueue = mLooper.mQueue;

1-3,初始化callback

         mCallback = callback;

2,Handler的常用几种方法有哪些?


        public final Message obtainMessage()        {            return Message.obtain(this);        }        public final boolean postDelayed(Runnable r, long delayMillis)        {            return sendMessageDelayed(getPostMessage(r), delayMillis);        }            public final void removeCallbacks(Runnable r)        {            mQueue.removeMessages(this, r, null);        }        public final boolean sendMessageDelayed(Message msg, long delayMillis)        {            if (delayMillis < 0) {                delayMillis = 0;            }            return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);        }

3,Handler把Meesage发送到什么地方去了?


当Handler调用sendMessage方法时,Handler会把Message放入到Looper的MessageQueue中。

值得注意的是,sendMessage时,Handler把自己对象引用也给Message,在Message成员变量target里

        public final boolean sendMessage(Message msg)        {            return sendMessageDelayed(msg, 0);        }        public final boolean sendMessageDelayed(Message msg, long delayMillis)        {            if (delayMillis < 0) {                delayMillis = 0;            }            return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);        }        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);        }        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {            msg.target = this;            if (mAsynchronous) {                msg.setAsynchronous(true);            }            return queue.enqueueMessage(msg, uptimeMillis);        }

4,MessageQueue是什么,他与Handler,Message,Looper存在什么样的关系?


MessageQueue拥有Message作为成员变量,而Message类中存在Message next成员变量与静态的Meesage sPools变量,

这就意味着Message类中存在自己的对象,自己当中包含自己,形成了一条链表结构,不亚于数组的结构。

Handler把Message交给MessageQueue之后,MessageQueue把这个Message对象引用下来

        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.next = p;                    mMessages = msg;

可以看到最后一行,mMessages成员变量拿到了传递进来的message引用

而Looper存在一个成员变量就是MessageQueue,在Looper的loop方法中,从MessageQueue找出已存在的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(); // 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.traceBegin(traceTag, msg.target.getTraceName(msg));                }                try {                    msg.target.dispatchMessage(msg);                } finally {                    if (traceTag != 0) {                        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();            }        }

看到for循环里的第一行,从MessageQueue取出Message了

接下来看Looper怎么处理Message的?

看着一行代码:

        msg.target.dispatchMessage(msg);

上面我们知道message的target就是Handler,绕了一圈,还是让Handler来处理这个Message,进入方法中:

        /**         * 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);            }        }        private static void handleCallback(Message message) {            message.callback.run();        }        public interface Callback {            public boolean handleMessage(Message msg);        }        public void handleMessage(Message msg) {        }

可以看到,首先判断message有没有callback,这个callback就是平时我们调用Handler.post(run)传递一个Runable对象回调的方法。

而mCallback是Handler内部的一个接口,也可以使用这个接口。最后才是回调handleMessage这个方法


最后,Message被回收:

        msg.recycleUnchecked();        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++;                }            }        }

5,Message源码分析


跟着Handler,sendMessage绕了一圈,路过MessageQueue,Looper,最后还是让Handler来处理这个Message。

那好,现在我们来研究一下这个Message

public final class Message implements Parcelable {    public int what;    public int arg1;     public int arg2;    public Object obj;    /*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;    private static final Object sPoolSync = new Object();    private static Message sPool;    private static int sPoolSize = 0;    private static final int MAX_POOL_SIZE = 50;

先看Message源码中的成员变量:

what,arg1,arg2,这些是用来区分Message来使用的,一般只用what,这里告诉你:这三个都可以随便用

long when 是message执行的时间

Handler target 这是就是引用的Handler了,每一个Message都知道自己是被哪一个Handler来处理的

Runnbale callback 这就是post传递进去的Runnable对象,也被Message拿到了,

所以说,sendMessage和post最终都是以Message的形式来处理的

Message next 这是Message里包含下一个Message,形成了单链表结构

static Message sPool 这就是传说中的消息池了,没错他就是一个Message对象而已,静态的成员变量。

static final int MAX_POOL_SIZE = 50; google工程师限时这个消息池的最大长度,50个


接来看我们来研究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();        }

可以看出,如过消息池为空,直接new出来。否则直接去池里取一个Message对象,把下一个Message设置到池里,池数目减减

如果谁以后创建Message还自己手动New的话,我在这先鄙视一下…

当使用完毕之后,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++;                }            }        }

这里把Message的成员变量清空个遍,sPool = this ,这行就是把Message还回池中了,池数目加加


6,Handler,Message,MessageQueue,Looper之间是怎么样工作的?


1,创建Handler,Handler获取到当前线程的Looper,Looper里的MessageQueue

2,创建Message,是通过池是否有消息来返回Message的,池一个都没有才会new

3,sendMessage与post,本质都是Message,最后获取Handler引用,Message被传递给了MessageQueue

4,Looper的loop方法,检查Looper的MesaageQueue是否有Message,有的话把Message传递给Handler来处理

5,Message回收


7,子线程也能使用Handler,MessageQueue,Looper机制吗?


去看Looper源码头上的注释就知道了:

        /**          * Class used to run a message loop for a thread.  Threads by default do          * not have a message loop associated with them; to create one, call          * {@link #prepare} in the thread that is to run the loop, and then          * {@link #loop} to have it process messages until the loop is stopped.          *          * <p>Most interaction with a message loop is through the          * {@link Handler} class.          *          * <p>This is a typical example of the implementation of a Looper thread,          * using the separation of {@link #prepare} and {@link #loop} to create an          * initial Handler to communicate with the Looper.          *          * <pre>          *  class LooperThread extends Thread {          *      public Handler mHandler;          *          *      public void run() {          *          Looper.prepare();          *          *          mHandler = new Handler() {          *              public void handleMessage(Message msg) {          *                  // process incoming messages here          *              }          *          };          *          *          Looper.loop();          *      }          *  }</pre>          */        public final class Looper {

google工程师都把代码写给你了。闲麻烦的话,那就去用google工程师又帮你写好的HandlerThread这个类吧,

子线程使用Handler,Looper机制。

什么时候用子线程开启Handler,Looper机制呢,看需求吧。Handler机制拥有Message 50个消息队列,

能很好的保证处理的任务或者消息以线性的方式来执行,在子线程保证线性执行噢。

但是不能玩太耗时的操作,毕竟是队列。

分析就到这里了


11/8/2016 4:29:08 PM

0 0
原创粉丝点击