Handler,MessageQueue,Runnable与Looper

来源:互联网 发布:python的idle mac 编辑:程序博客网 时间:2024/05/17 08:38

三者关系

Handler是处理消息或发送消息,MessageQueue存储消息,Runnable安排执行任务,Looper循环MessageQueue消息队列,并取出消息到给制定Handler处理。其三者具体关系如下:

  • 每个Thread只对应一个Looper。
  • 每个Looper只对应一个MessageQueue。
  • 每个MessageQueue中有N个Message。
  • 每个Message中最多指定一个Handler来处里消息(处理线程为Looper绑定的线程)。
    这里写图片描述
    采用这机制对消息进行处理,有下面两点好处:
  • 在多线程并发执行的同时,做出一些改变的时候,这方法可以避免了一些判断条件。
  • 一般来说,Thread一旦完成执行任务,就不可以重复执行新的任务,而采用这种机制它可以让Thread可以在后台重复执行任务,而不用创建新的Thread实例,因为它的生命周期是伴随Looper的生命周期,只要Looper不调用quit 方法,Thread的生命周期就不会结束。

Handler

handler这个角色起着两个重要作用,一是:处理Message;二是:将某个Message压入MessageQueue。
构造函数源码分析:

  //默认设置Looper和MessageQueue    public Handler(Callback callback, boolean async) {        if (FIND_POTENTIAL_LEAKS) {            final Class<? extends Handler> klass = getClass();            //检查Handler是否是时静态内部类,静态实例,静态匿名类,不是发出内存泄漏警告            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        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;    }    //自定义设置Looper和MessageQueue       public Handler(Looper looper, Callback callback, boolean async) {        mLooper = looper;        mQueue = looper.mQueue;        mCallback = callback;        mAsynchronous = async;    }

从源码分析可以看出,如果你创建Handler实例时,当地线程没有Looper实例且有没有传入Looper实例,就会抛出Can't create handler inside thread that has not called Looper.prepare() 异常。
发送消息源码分析:

    //发送任务    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 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));    }    //将Runnable封装成Message消息    private static Message getPostMessage(Runnable r) {        //从消息池获取Message        Message m = Message.obtain();        m.callback = r;        return m;    }    //定时发送消息到MessageQueue     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) {    //绑定处理消息处理的Handler        msg.target = this;        if (mAsynchronous) {            msg.setAsynchronous(true);        }        //插入消息到MessageQueue        return queue.enqueueMessage(msg, uptimeMillis);    }    //插入消息    boolean enqueueMessage(Message msg, long when) {    //检查该消息是否有对应的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) {            //检查Looper循环是否已停止            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;            //检查是否是msg头部消息(即原本消息队列为空)或处于空闲等待状态,如果是唤醒休眠的事件队列            if (p == null || when == 0 || when < p.when) {                //m该sg为头部                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;                //寻找msg执行后的下一个执行消息                for (;;) {                    prev = p;                    p = p.next;                    //若到消息队列结束或下一个将要执行的消息大于msg的延时时间,                    if (p == null || when < p.when) {                        break;                    }                    //如果是异步,则不用唤醒                    if (needWake && p.isAsynchronous()) {                        needWake = false;                    }                }                //下一个将要执行的message对象                msg.next = p;                 prev.next = msg;            }            // We can assume mPtr != 0 because mQuitting is false.            if (needWake) {                //调用本地方法唤醒主线程                nativeWake(mPtr);            }        }        return true;    }

从源码分析来看,发送消息事,传送的Runnable对象会被封装成Message对象,插入到消息队列。
处理消息源码分析:

     //分发消息    public void dispatchMessage(Message msg) {           if (msg.callback != null) {         //执行Runnable任务            handleCallback(msg);        } else {            //new Callback任务            if (mCallback != null) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            //执行我们重写的handlerMessage方法            handleMessage(msg);        }    }    //执行Runnable的run方法     private static void handleCallback(Message message) {        message.callback.run();    }    //回调接口    public interface Callback {        public boolean handleMessage(Message msg);    }

从源码分析来看,Handler处理消息过程如图:
这里写图片描述

MessageQueue

构造函数源码分析:

//调用本地方法初始化MessageQueue(boolean quitAllowed) {        //是否运行线程退出Looper循环,主线程默认不可以退出Looper循环        mQuitAllowed = quitAllowed;        mPtr = nativeInit();    }//本地方法实现static jint android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {    //创建本地NativeMessageQueue对象    NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();    if (!nativeMessageQueue) {        jniThrowRuntimeException(env, "Unable to allocate native queue");        return 0;    }    //增加引用计数    nativeMessageQueue->incStrong(env);    return reinterpret_cast<jint>(nativeMessageQueue);}

本地的NativeMessageQueue构造方法源码分析:

NativeMessageQueue::NativeMessageQueue() : mInCallback(false), mExceptionObj(NULL) {    //获取本地方法的Looper对象    mLooper = Looper::getForThread();    if (mLooper == NULL) {        //没有创建本地Looper对象,并epoll中监听回调不允许为空        mLooper = new Looper(false);        Looper::setForThread(mLooper);    }}

本地Looper的构造方法源码分析:

Looper::Looper(bool allowNonCallbacks) :        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),        mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {      //存储管道读写端的句柄    int wakeFds[2];    int result = pipe(wakeFds);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);    mWakeReadPipeFd = wakeFds[0];    mWakeWritePipeFd = wakeFds[1];    //创建管道读端的句柄    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",            errno);     //创建管道写端的句柄    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",            errno);    mIdling = false;    // 创建epoll句柄,并传入能监听文件句柄的最大数量.    mEpollFd = epoll_create(EPOLL_SIZE_HINT);    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);    struct epoll_event eventItem;    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union    eventItem.events = EPOLLIN;    eventItem.data.fd = mWakeReadPipeFd;    //注册管道监听,一旦管道有内容可读,就唤醒正在等待管道中的线程    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",            errno);}

从源码分析可以知道,其进程通信采用管道机制和linux的epoll机制,对于管道机制来说,一般的使用方式就是,一个线程通过读文件描述符中来读管道的内容,当管道没有内容时,这个线程就会进入等待状态,而另外一个线程通过写文件描述符来向管道中写入内容,写入内容的时候,如果另一端正有线程正在等待管道中的内容,那么这个线程就会被唤醒。至于如何唤醒是借用通过linux的epoll机制。linux的epoll机制可以参考下面文章了解:
http://blog.csdn.net/zhaozhanyong/article/details/5410887
从上面源勉分析来看,java层的MessageQueue,Looper和native层的MessageQueue,Looper一一对应,其关系如图:
这里写图片描述

Looper

Looper的创建源码分析:

//普通线程调用其创建Looper对象,其Looper循环可以退出public static void prepare() {        prepare(true);    }    //UI线程调用其创建Looper对象,UI线程默认调用,其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();        }    }    //创建Looper对象,quitAllowed参数控制Looper循环是否可以退出    private static void prepare(boolean quitAllowed) {        if (sThreadLocal.get() != null) {            throw new RuntimeException("Only one Looper may be created per thread");        }        sThreadLocal.set(new Looper(quitAllowed));    }//Looper构造方法private Looper(boolean quitAllowed) {        //创建消息队列        mQueue = new MessageQueue(quitAllowed);        //绑定本线程        mThread = Thread.currentThread();    }

从源码看出,Looper对象会通过内部构造方法绑定一个消息队列,而普通线程是通过Looper.prepare() 方法创建Looper和MessageQueue对象,且默认Looper循环可以退出,而主线程是通过Looper.prepareMainLooper() 创建对象Looper和MessageQueue对象,且默认Looper循环不可以退出。
循环消息源码分析:

    //循环取出消息,直到调用quit()方法退出    public static void loop() {        final Looper me = myLooper();        //检查是否有Looper对象        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            //当调用了quit方法            if (msg == null) {                //退出循环                return;            }            // This must be in a local variable, in case a UI event sets the logger            //Log日志对象            Printer logging = me.mLogging;            if (logging != null) {                logging.println(">>>>> Dispatching to " + msg.target + " " +                        msg.callback + ": " + msg.what);            }            //进行消息处理            msg.target.dispatchMessage(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);            }            //回收消息对象            msg.recycleUnchecked();        }    }

从源码分析可以看出,Looper实际通过MessageQueue.next() 方法取出消息。
MessageQueue.next()取出消息的方法源码分析:

 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.        //验证epoll句柄是否创建成功        final long ptr = mPtr;        if (ptr == 0) {            return null;        }        //运行空闲Handler的数量                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;                 // 如果当前消息非空,但是当前消息的处理handle是空;则获取第一个异步消息                if (msg != null && msg.target == null) {                    // Stalled by a barrier.  Find the next asynchronous message in the queue.                    do {                        prevMsg = msg;                        msg = msg.next;                    } while (msg != null && !msg.isAsynchronous());                }                //当当前消息非空,且有对应处理handle或当前消息的是异步消息                if (msg != null) {                    if (now < msg.when) {                        // 如果当前消息还不到执行,就设置一个和现在时间差的等待执行时间                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);                    }                    //如果该消息到了执行时间                    else {                        // Got a message.                        mBlocked = false;                        //当当前执行消息为取出的第一个异步消息,删除异步消息,连接异步消息下一个消息                        if (prevMsg != null) {                            prevMsg.next = msg.next;                        }                        //当当前执行消息是有对应的handle消息时,连接一下个消息                        else {                            mMessages = msg.next;                        }                        msg.next = null;                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);                        //标记该消息对象被使用                        msg.markInUse();                        return msg;                    }                } else {                    // 没有消息时                    nextPollTimeoutMillis = -1;                }                // Process the quit message now that all pending messages have been handled.                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)) {                    //获取正在运行的空闲Handler数目                    pendingIdleHandlerCount = mIdleHandlers.size();                }                if (pendingIdleHandlerCount <= 0) {                    //没有空闲的Handler正在运行,那么Looper会阻塞等待                    mBlocked = true;                    continue;                }                //第一次调用next()方法时候会创建四个空闲的Handler对象实例                if (mPendingIdleHandlers == null) {                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];                }                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);            }            //只在第一次调用该next()方法时,才会执行到下面代码去运行空闲的Handlers            for (int i = 0; i < pendingIdleHandlerCount; i++) {                final IdleHandler idler = mPendingIdleHandlers[i];                mPendingIdleHandlers[i] = null; // release the reference to the handler                //是否保持该空闲Handler运行的标记                boolean keep = false;                try {                    keep = idler.queueIdle();                } catch (Throwable t) {                    Log.wtf(TAG, "IdleHandler threw exception", t);                }                //停止该空闲Handler的运行                if (!keep) {                    synchronized (this) {                        mIdleHandlers.remove(idler);                    }                }            }            // 设置空闲Handler数量为0,防止再次创建和运行空闲Handler            pendingIdleHandlerCount = 0;            //通过运行空闲的Handler去等待新的Message到来,而不是通过阻塞状态            nextPollTimeoutMillis = 0;        }    }

本地方法的pollOnce源码分析:

static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jclass clazz,        jint ptr, jint timeoutMillis) {    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);    //调用本地MessageQeueu的pollOnce方法    nativeMessageQueue->pollOnce(env, timeoutMillis);}//本地轮询方法的实现void NativeMessageQueue::pollOnce(JNIEnv* env, int timeoutMillis) {    mInCallback = true;    //调用本地Looper的pollOnce方法    mLooper->pollOnce(timeoutMillis);    mInCallback = false;    if (mExceptionObj) {        env->Throw(mExceptionObj);        env->DeleteLocalRef(mExceptionObj);        mExceptionObj = NULL;    }}//本地Looper的轮询方法实现,获取下一个执行的消息,以唤醒线程int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {    int result = 0;    //这里很多地方看不太懂,就直接看pollInner(timeoutMillis)方法    for (;;) {        while (mResponseIndex < mResponses.size()) {            const Response& response = mResponses.itemAt(mResponseIndex++);            int ident = response.request.ident;            if (ident >= 0) {                int fd = response.request.fd;                int events = response.events;                void* data = response.request.data;#if DEBUG_POLL_AND_WAKE                ALOGD("%p ~ pollOnce - returning signalled identifier %d: "                        "fd=%d, events=0x%x, data=%p",                        this, ident, fd, events, data);#endif                if (outFd != NULL) *outFd = fd;                if (outEvents != NULL) *outEvents = events;                if (outData != NULL) *outData = data;                return ident;            }        }        if (result != 0) {#if DEBUG_POLL_AND_WAKE            ALOGD("%p ~ pollOnce - returning result %d", this, result);#endif            if (outFd != NULL) *outFd = 0;            if (outEvents != NULL) *outEvents = 0;            if (outData != NULL) *outData = NULL;            return result;        }        result = pollInner(timeoutMillis);    }}

本地Looper的pollInner()源码分析:

int Looper::pollInner(int timeoutMillis) {#if DEBUG_POLL_AND_WAKE    ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);#endif    // Adjust the timeout based on when the next message is due.    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);        if (messageTimeoutMillis >= 0                && (timeoutMillis <0 || messageTimeoutMillis < timeoutMillis)) {            timeoutMillis = messageTimeoutMillis;        }#if DEBUG_POLL_AND_WAKE        ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",                this, mNextMessageUptime - now, timeoutMillis);#endif    }    // Poll.    int result = ALOOPER_POLL_WAKE;    mResponses.clear();    mResponseIndex = 0;    struct epoll_event eventItems[EPOLL_MAX_EVENTS];    //等待消息队列的事件发生,就是被监听的消息管道,一旦管道有可读内容,线程就会被唤醒    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);    // Acquire lock.    mLock.lock();    //轮询监听出错,则直接跳到Done处.    if (eventCount <0) {        if (errno == EINTR) {            goto Done;        }        ALOGW("Poll failed with an unexpected error, errno=%d", errno);        result = ALOOPER_POLL_ERROR;        goto Done;    }    // 超时,就是在一定超时设置时间范围内,还没有产生可读内容事件,则直接跳到Done处。    if (eventCount == 0) {#if DEBUG_POLL_AND_WAKE        ALOGD("%p ~ pollOnce - timeout", this);#endif        result = ALOOPER_POLL_TIMEOUT;        goto Done;    }    // Handle all events.#if DEBUG_POLL_AND_WAKE    ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);#endif    // 如果有可读内容事件发生,则逐个取出消息,如果是是写事件(EPOLLIN),则调用awoken()唤醒线程    for (int i = 0; i <eventCount; i++) {        int fd = eventItems[i].data.fd;        uint32_t epollEvents = eventItems[i].events;        if (fd == mWakeReadPipeFd) {            if (epollEvents & EPOLLIN) {                awoken();            } else {                ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);            }        } else {            ssize_t requestIndex = mRequests.indexOfKey(fd);            if (requestIndex >= 0) {                int events = 0;                if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;                if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;                if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;                if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;                pushResponse(events, mRequests.valueAt(requestIndex));            } else {                ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "                        "no longer registered.", epollEvents, fd);            }        }    }Done: ;    // Invoke pending message callbacks.    mNextMessageUptime = LLONG_MAX;    while (mMessageEnvelopes.size() != 0) {        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);        if (messageEnvelope.uptime <= now) {            // Remove the envelope from the list.            // We keep a strong reference to the handler until the call to handleMessage            // finishes.  Then we drop it so that the handler can be deleted *before*            // we reacquire our lock.            { // obtain handler                sp<MessageHandler> handler = messageEnvelope.handler;                Message message = messageEnvelope.message;                mMessageEnvelopes.removeAt(0);                mSendingMessage = true;                mLock.unlock();#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS                ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",                        this, handler.get(), message.what);#endif                handler->handleMessage(message);            } // release handler            mLock.lock();            mSendingMessage = false;            result = ALOOPER_POLL_CALLBACK;        } else {            // The last message left at the head of the queue determines the next wakeup time.            mNextMessageUptime = messageEnvelope.uptime;            break;        }    }    // Release lock.    mLock.unlock();    // Invoke all response callbacks.    for (size_t i = 0; i <mResponses.size(); i++) {        Response& response = mResponses.editItemAt(i);        if (response.request.ident == ALOOPER_POLL_CALLBACK) {            int fd = response.request.fd;            int events = response.events;            void* data = response.request.data;#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS            ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",                    this, response.request.callback.get(), fd, events, data);#endif            int callbackResult = response.request.callback->handleEvent(fd, events, data);            if (callbackResult == 0) {                removeFd(fd);            }            // Clear the callback reference in the response structure promptly because we            // will not clear the response vector itself until the next poll.            response.request.callback.clear();            result = ALOOPER_POLL_CALLBACK;        }    }    return result;}//读取管道内容,来唤醒线程void Looper::awoken() {#if DEBUG_POLL_AND_WAKE    ALOGD("%p ~ awoken", this);#endif    char buffer[16];    ssize_t nRead;    do {        //唤醒线程        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));}

从源码分析来看,pollInner()就是先通过epoll_wait()进入空闲等待状态,等待消息队列的管道上的消息(IO事件),如果有消息待处理(即管道上有IO写事件发生,写事件是EPOLLIN类型),则调用awoken()(通过往管道中读数据来使处于空闲等待状态的主线程继续运行)将消息读取出来.

总结

总过上面java层到native层的分析,可以很清楚知道Handler,MessageQueue,Looper在java层和native层之间的关系和协作,其整个过程如图:
创建实例过程:
这里写图片描述
取出消息过程:
这里写图片描述
参考资料:
http://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/
http://blog.nikitaog.me/2014/10/18/android-looper-handler-handlerthread-ii/
http://wangkuiwu.github.io/2014/08/26/MessageQueue/
http://www.programering.com/a/MjM2QDMwATc.html

1 0
原创粉丝点击