Android之Handler、Looper、MessageQueue

本章节会按照下面的流程讲解消息处理机制:

  • Java层实现机制
      1. 概念
    • 2.消息处理的两种方式:
      • 1)sendMessage and handleMessage
      • 2)post and handleCallback
  • Native层实现机制
      1. SurfaceFlinger启动
      1. 两种案例:
      • 1) createSurface
      • 2)onMessageReceived
      1. Mutex/Condition/Barrier

一.Java层实现机制

1.概念

1)属于异步消息处理机制,线程启动后会进入一个无限的循环体(Looper)之中,每循环一次,从其内部的消息队列(MessageQueue)中取出一个消息,然后回调相应的消息处理函数(Handler),执行完成一个消息后则继续循环。若消息队列为空,线程则会阻塞等待。其它线程负责发送消息(Handler)到UI线程处理(Handler);
2)发送消息有Handler的sendMessage、post等,处理消息都是通过dispatchMessage处理(分两路一路处理post的run方法,一路处理sendMessage的handleMessage方法);
3)首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue相关联;
然后,Looper.loop()会让当前线程进入一个无限循环,不断从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法;
最后,Handler的sendMessage方法(或者post),会给msg的target赋值为handler自身,然后加入MessageQueue中;
4)在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。

2. 消息处理的两种方式

1)sendMessage and handleMessage

frameworks/base/core/java/android/app/ActivityThread.java

6687    public static void main(String[] args) {

6706        Looper.prepareMainLooper();

6708        ActivityThread thread = new ActivityThread();

6709        thread.attach(false);

6711        if (sMainThreadHandler == null) {

6712            sMainThreadHandler = thread.getHandler();

6713        }

6722        Looper.loop();

a. 首先,调用prepareMainLooper,即调用Looper的prepare方法,因为是首次调用所以会向sThreadLocal中set一个new出来的Looper对象。也就是说,prepareMainLooper目的是向当前主线程UI线程中增加一个Looper对象。


frameworks/base/core/java/android/os/Looper.java

106    public static void prepareMainLooper() {

107        prepare(false);

93    private static void prepare(boolean quitAllowed) {

94        if (sThreadLocal.get() != null) {

95            throw new RuntimeException("Only one Looper may be created per thread");

96        }

97        sThreadLocal.set(new Looper(quitAllowed));

98    }

//Looper对象中保存MessageQueue对象mQueue

216    private Looper(boolean quitAllowed) {

217        mQueue = new MessageQueue(quitAllowed);

218        mThread = Thread.currentThread();

219    }

b. 然后调用ActivityThread的attach方法。而该函数内会通过binder IPC机制向ServiceManager获取AMS服务。然后会调用AMS的attachApplication,分析见下:

frameworks/base/core/java/android/app/ActivityThread.java
237    final ApplicationThread mAppThread = new ApplicationThread();
6534    private void attach(boolean system) {
6547            final IActivityManager mgr = ActivityManager.getService();
6551                mgr.attachApplication(mAppThread);

在AMS中会回调ApplicationThread的bindApplication方法。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
7330    public void attachApplication(IApplicationThread thread) {
7334            attachApplicationLocked(thread, callingPid);
7023    private final boolean attachApplicationLocked(IApplicationThread thread,
7024            int pid) {
7230                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,

而在ApplicationThread的bindApplication方法中会sendMessage。

frameworks/base/core/java/android/app/ActivityThread.java
959        public final void bindApplication(String processName, ApplicationInfo appInfo,
993            sendMessage(H.BIND_APPLICATION, data);
2666    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
//获取new Message对象,比直接new好
2670        Message msg = Message.obtain(); 
//初始化Message对象
2671        msg.what = what;
2672        msg.obj = obj;
2673        msg.arg1 = arg1;
2674        msg.arg2 = arg2;
2675        if (async) {
2676            msg.setAsynchronous(true);
2677        }
//mH在ActivityThread开头就已经初始化了
2678        mH.sendMessage(msg);
2679    }
//new H的时候会new Handler
239    final H mH = new H();
1523    private class H extends Handler
2031    final Handler getHandler() {
2032        return mH;
2033    }

在activityThread一开始执行时就会new Handler,会得到上面set进sThreadLocal中的Looper对象。几个类之间关系如下:


Android之Handler、Looper、MessageQueue_第1张图片
Looper/MessageQueue/Handler
frameworks/base/core/java/android/os/Handler.java
//Handler对象中保存
192    public Handler(Callback callback, boolean async) {
202        mLooper = Looper.myLooper();
207        mQueue = mLooper.mQueue;
208        mCallback = callback;
frameworks/base/core/java/android/os/Looper.java
203    public static @Nullable Looper myLooper() {
204        return sThreadLocal.get();
205    }

上面的sendMessage会调用父类Handler的sendMessage,向MessagQueue中插入消息。
这就是为什么Handler中要拿MessageQueue的原因了,而拿MessageQueue需要通过Looper间接拿到。

frameworks/base/core/java/android/os/Handler.java
536    public final boolean sendMessage(Message msg)
537    {
538        return sendMessageDelayed(msg, 0);
539    }

596    public final boolean sendMessageDelayed(Message msg, long delayMillis)
597    {
598        if (delayMillis < 0) {
599            delayMillis = 0;
600        }
601        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
602    }

623    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
624        MessageQueue queue = mQueue;
625        if (queue == null) {
626            RuntimeException e = new RuntimeException(
627                    this + " sendMessageAtTime() called with no mQueue");
628            Log.w("Looper", e.getMessage(), e);
629            return false;
630        }
631        return enqueueMessage(queue, msg, uptimeMillis);
632    }

c. 最后sMainThreadHandler得到的是Handler对象,调用Looper.loop

frameworks/base/core/java/android/os/Looper.java
129    public static void loop() {
130        final Looper me = myLooper();
141        for (;;) {
142            Message msg = queue.next(); // might block
164                msg.target.dispatchMessage(msg);
195            msg.recycleUnchecked();

首先会获取线程中存储的Looper对象,然后循环从MessageQueue中取走Message。
最后调用dispatchMessage去处理Message

frameworks/base/core/java/android/os/Handler.java
97    public void dispatchMessage(Message msg) {
98        if (msg.callback != null) {
99            handleCallback(msg);
100        } else {
101            if (mCallback != null) {
102                if (mCallback.handleMessage(msg)) {
103                    return;
104                }
105            }
106            handleMessage(msg);
107        }
108    }

如果Message中没有初始化callback的话(即不是以post形式插入消息,而是以sendMessage形式插入MessageQueue中)会走handleMessage,一般都会重新handler时处理(因为Handler.java中实现为空)。

这里先讲解第一步的sendMessage对应的handleMessage:

frameworks/base/core/java/android/app/ActivityThread.java
1523    private class H extends Handler {
1641        public void handleMessage(Message msg) {
1714                case BIND_APPLICATION:
1715                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1716                    AppBindData data = (AppBindData)msg.obj;
1717                    handleBindApplication(data);
1718                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1719                    break;

这样就完成了一次消息机制。

2) post and handleCallback

a. 首先构造一个Message,然后将Message放入到MessageQueue中,唯一不同的是obtain方法参数不同,详细见下:

frameworks/base/core/java/android/view/Choreographer.java
150    private final FrameHandler mHandler;
838    private final class FrameDisplayEventReceiver extends DisplayEventReceiver
839            implements Runnable {
849        public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
889            Message msg = Message.obtain(mHandler, this);
890            msg.setAsynchronous(true);
891            mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);

在obtain中构造的Message的target为FrameHandler对象,callback为FrameDisplayEventReceiver对象。

frameworks/base/core/java/android/os/Message.java
180    public static Message obtain(Handler h, Runnable callback) {
181        Message m = obtain();
182        m.target = h;
183        m.callback = callback;
184
185        return m;
186    }

b. 在Handler.java中dispatchMessage函数处理Message时,因为callback不为空,所以会走handleCallback(msg);

frameworks/base/core/java/android/os/Handler.java
789    private static void handleCallback(Message message) {
790        message.callback.run();
791    }

因此,最终会调用FrameDisplayEventReceiver类的run方法,实现一次消息处理。

frameworks/base/core/java/android/view/Choreographer.java
838    private final class FrameDisplayEventReceiver extends DisplayEventReceiver
839            implements Runnable {
895        public void run() {
896            mHavePendingVsync = false;
897            doFrame(mTimestampNanos, mFrame);
898        }

二. Native层实现机制

参考下高手对surfaceflinger启动流程图:


Android之Handler、Looper、MessageQueue_第2张图片
image.gif

1. surfaceflinger启动

首先看下main堆栈,具体指导surfaceflinger干了什么
SurfaceFlinger启动后主线程堆栈如下:

  #00 pc 000000000006f610  /system/lib64/libc.so (__epoll_pwait+8)
  #01 pc 00000000000141c8  /system/lib64/libutils.so (android::Looper::pollInner(int)+144)
  #02 pc 0000000000014094  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+60)
  #03 pc 000000000009993c  /system/lib64/libsurfaceflinger.so (android::impl::MessageQueue::waitMessage()+92)
  #04 pc 00000000000a88b4  /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::run()+20)
  #05 pc 00000000000031b0  /system/bin/surfaceflinger (main+936)
  #06 pc 00000000000ae2e8  /system/lib64/libc.so (__libc_init+88)

对应代码如下:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::run() {
    do {
        waitForEvent();
    } while (true);
}

void SurfaceFlinger::waitForEvent() {
    mEventQueue->waitMessage();
}

进入MessageQueue中,首先看下初始化过程中重要的Looper对象和Hnadler对象。

frameworks/native/services/surfaceflinger/MessageQueue.cpp
void MessageQueue::init(const sp& flinger) {
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}

void MessageQueue::waitMessage() {
    do {
        IPCThreadState::self()->flushCommands();
        int32_t ret = mLooper->pollOnce(-1);
        switch (ret) {
            case Looper::POLL_WAKE:
            case Looper::POLL_CALLBACK:
                continue;
            case Looper::POLL_ERROR:
                ALOGE("Looper::POLL_ERROR");
                continue;
            case Looper::POLL_TIMEOUT:
                // timeout (should not happen)
                continue;
            default:
                // should not happen
                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                continue;
        }
    } while (true);
}

主要研究下Looper,利用Looper对象的pollOnce方法(epoll_wait函数)来阻塞sf主线成来等待消息事件的到来。

system/core/libutils/include/utils/Looper.h
inline int pollOnce(int timeoutMillis) {
        return pollOnce(timeoutMillis, NULL, NULL, NULL);
}

int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
     ...
     result = pollInner(timeoutMillis);
     ...
}

int Looper::pollInner(int timeoutMillis) {
    ...
    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);   //阻塞等待消息到
来
...
          { // obtain handler
                sp handler = messageEnvelope.handler;
                Message message = messageEnvelope.message;
                mMessageEnvelopes.removeAt(0);
                mSendingMessage = true;
                mLock.unlock();
                handler->handleMessage(message);          //到来之后执行MessageHandler的handleMessage
            } // release handler

void Looper::sendMessage(const sp& handler, const Message& message) {
    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    sendMessageAtTime(now, handler, message);
}
void Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp& handler,
        const Message& message) {
    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    sendMessageAtTime(now + uptimeDelay, handler, message);
}
void Looper::sendMessageAtTime(nsecs_t uptime, const sp& handler,
        const Message& message) {
    ...
    if (i == 0) {
        wake();
    }
}

那么再分析下什么时候sf主线成不会受到阻塞呢?
那就是有sendMessage过来,然后执行handler->handleMessage(message);

class MessageHandler : public virtual RefBase {
protected:
    virtual ~MessageHandler();
public:
    virtual void handleMessage(const Message& message) = 0;
};

其中handler类型为MessageHandler,其中handleMessage为纯虚函数,由此可见会传入MessageHandler的子类(搜了下只有MessageBase)对象赋值给handler,并执行子类重写的handleMessage。

class MessageBase : public MessageHandler {
public:
    MessageBase();
    // return true if message has a handler
    virtual bool handler() = 0;        //纯虚函数,还有子类的实现

    // waits for the handler to be processed
    void wait() const { barrier.wait(); }
protected:
    virtual ~MessageBase();
private:
    virtual void handleMessage(const Message& message);
    mutable Barrier barrier;
};
MessageBase::MessageBase() : MessageHandler() {}
MessageBase::~MessageBase() {}
void MessageBase::handleMessage(const Message&) {
    this->handler();
    barrier.open();
};

而MessageBase的handleMessage函数中两个重要函数,第一个调用其子类的handler函数去处理消息,第二为Barrier的open去取消阻塞。

现在我们先看下哪有sendMessage或者是sendMessageDelayed。

status_t MessageQueue::postMessage(const sp& messageHandler, nsecs_t relTime) {
    const Message dummyMessage;
    if (relTime > 0) {
        mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
    } else {
        mLooper->sendMessage(messageHandler, dummyMessage);
    }
    return NO_ERROR;
}
status_t SurfaceFlinger::postMessageAsync(const sp& msg,
        nsecs_t reltime, uint32_t /* flags */) {
    return mEventQueue->postMessage(msg, reltime);
}
status_t SurfaceFlinger::postMessageSync(const sp& msg,
        nsecs_t reltime, uint32_t /* flags */) {
    status_t res = mEventQueue->postMessage(msg, reltime);
    if (res == NO_ERROR) {
        msg->wait();
    }
    return res;
}

可以看到surfaceflinger有两处会sendMessage,一个同步的一个异步的。

2. 两种案例

举两个典型的例子吧,一个是createSurface,一个onMessageReceived。

1) createSurface

virtual bool handler() {
            result = flinger->createLayer(name, client, w, h, format, flags,
                    windowType, ownerUid, handle, gbp, parent);
            return true;
        }
    };

    sp msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle,
            windowType, ownerUid, gbp, &parent);
    mFlinger->postMessageSync(msg);

同步过程多了一个msg->wait(),这个函数会通过barrier.wait(); 还记得 barrier.open();了吗?在MessageBase::handleMessage时首先去处理消息然后open。

因此:postMessageSync在binder线程中,而createLayer在UI线程中,当UI线程执行完毕后会通过Barrier::open 去唤醒binder线程。

2) onMessageReceived

class Handler : public MessageHandler {
    public:
        explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
        virtual void handleMessage(const Message& message);
        void dispatchRefresh();
        void dispatchInvalidate();
};
void MessageQueue::Handler::handleMessage(const Message& message) {
    switch (message.what) {
        case INVALIDATE:
            android_atomic_and(~eventMaskInvalidate, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
        case REFRESH:
            android_atomic_and(~eventMaskRefresh, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
    }
}

当受到底层的vsync信号后,会执行cb_eventReceiver(具体可以去分析下vsync信号的传入过程),会调用dispatchInvalidate,这也是会sendMessage的。

void MessageQueue::Handler::dispatchInvalidate() {
    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
    }
}

因此,从systrace可以看出来createLayer和onMessageReceived是同步的:


image.gif

3.Mutex/Condition/Barrier

上面说到了Mutex,那么接下来我们就简单分析下Mutex机制:

system/core/libutils/include/utils/Condition.h        //也是支持跨进程传输的
# include 
pthread_cond_t mCond;
inline Condition::Condition(int type) {
...
pthread_cond_init(&mCond, &attr);
...
}
inline status_t Condition::wait(Mutex& mutex) {
    return -pthread_cond_wait(&mCond, &mutex.mMutex);
}

pthread_cond_wait函数主要工作为:
1)释放资源锁mutex,这样open函数才能拿到资源锁
2)进入休眠等待
3)如果被唤醒会再次持有mutex资源锁

inline void Condition::signal() {
    pthread_cond_signal(&mCond);
}
inline void Condition::broadcast() {       //通知所有等待者
    pthread_cond_broadcast(&mCond);
}

再往上点,surfaceflinger对此又做了一次封装:

frameworks/native/services/surfaceflinger/Barrier.h
mutable     Condition   cv;
mutable     Mutex       lock;
void wait() const {
        Mutex::Autolock _l(lock);
        while (state == CLOSED) {     //这个是condition的条件,只有为false的时候才会唤醒
            cv.wait(lock);
        }
}
 void open() {
        Mutex::Autolock _l(lock);
        state = OPENED;
        cv.broadcast();
}

那么有没有想过Mutex是什么呢?

system/core/libutils/include/utils/Mutex.h
# include 
Mutex& mLock;
pthread_mutex_t mMutex;
inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { mLock.lock(); }
inline ~Autolock() RELEASE() { mLock.unlock(); }
inline Mutex::Mutex() {
    pthread_mutex_init(&mMutex, NULL);
}
inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
    if (type == SHARED) {//跨进程间同步,AudioTrack和AudioFlinger就是驻留在两个不同进程中(frameworks/av/include/private/media/AudioEffectShared.h)
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
        pthread_mutex_init(&mMutex, &attr);
        pthread_mutexattr_destroy(&attr);
    } else {                         //单个进程间的多线程同步
        pthread_mutex_init(&mMutex, NULL);
    }
}
inline Mutex::~Mutex() {
    pthread_mutex_destroy(&mMutex);
}
inline Mutex::~Mutex() {
    pthread_mutex_destroy(&mMutex);
}
inline status_t Mutex::lock() {
    return -pthread_mutex_lock(&mMutex);
}
inline void Mutex::unlock() {
    pthread_mutex_unlock(&mMutex);
}
inline status_t Mutex::tryLock() {
    return -pthread_mutex_trylock(&mMutex);
}

因此,定义Mutex lock;时就是pthread_mutex_init完成初始化,在构造Mutex::Autolock _l(lock);时就是通过lock变量就去调用Mutex::lock函数实现pthread_mutex_lock,在作用域结束后会自动unlock。
Barrier > Condition > Mutex
1 ) Barrier 同时基于Condition和Mutex 实现
2 ) Condition 依赖Mutet完成

你可能感兴趣的:(Android之Handler、Looper、MessageQueue)