本章节会按照下面的流程讲解消息处理机制:
- Java层实现机制
-
- 概念
- 2.消息处理的两种方式:
- 1)sendMessage and handleMessage
- 2)post and handleCallback
-
- Native层实现机制
-
- SurfaceFlinger启动
-
- 两种案例:
- 1) createSurface
- 2)onMessageReceived
-
- 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对象。几个类之间关系如下:
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启动流程图:
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是同步的:
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完成