1. 概述
代碼路徑
framework/base/core/java/andorid/os/
- Handler.java
- Looper.java
- Message.java
- MessageQueue.java
1.1 架構(gòu)介紹:
消息機(jī)制主要包含:
- Message:消息分為硬件產(chǎn)生的消息(如按鈕拒逮、觸摸)和軟件生成的消息艘儒;
-
MessageQueue:消息隊(duì)列的主要功能向消息池投遞消息(
MessageQueue.enqueueMessage
)和取走消息池的消息(MessageQueue.next
)艺糜; -
Handler:消息輔助類黍图,主要功能向消息池發(fā)送各種消息事件(
Handler.sendMessage
)和處理相應(yīng)消息事件(Handler.handleMessage
)七咧; -
Looper:不斷循環(huán)執(zhí)行(
Looper.loop
)踏施,按分發(fā)機(jī)制將消息分發(fā)給目標(biāo)處理者
1.2 應(yīng)用示例
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
//TODO 定義消息處理邏輯.
}
};
Looper.loop();
}
}
1.3 ThreadLocal
ThreadLocal: 線程本地存儲(chǔ)區(qū)(Thread Local Storage,簡(jiǎn)稱為TLS)
每個(gè)線程都有自己的私有的本地存儲(chǔ)區(qū)域宙项,不同線程之間彼此不能訪問(wèn)對(duì)方的TLS區(qū)域乏苦。TLS常用的操作方法:
-
ThreadLocal.set(T value)
:將value存儲(chǔ)到當(dāng)前線程的TLS區(qū)域,源碼如下:
public void set(T value) {
Thread currentThread = Thread.currentThread(); //獲取當(dāng)前線程
Values values = values(currentThread); //查找當(dāng)前線程的本地儲(chǔ)存區(qū)
if (values == null) {
//當(dāng)線程本地存儲(chǔ)區(qū)尤筐,尚未存儲(chǔ)該線程相關(guān)信息時(shí)汇荐,則創(chuàng)建Values對(duì)象
values = initializeValues(currentThread);
}
//保存數(shù)據(jù)value到當(dāng)前線程this
values.put(this, value);
}
-
ThreadLocal.get()
:獲取當(dāng)前線程TLS區(qū)域的數(shù)據(jù),源碼如下:
public T get() {
Thread currentThread = Thread.currentThread(); //獲取當(dāng)前線程
Values values = values(currentThread); //查找當(dāng)前線程的本地儲(chǔ)存區(qū)
if (values != null) {
Object[] table = values.table;
int index = hash & values.mask;
if (this.reference == table[index]) {
return (T) table[index + 1]; //返回當(dāng)前線程儲(chǔ)存區(qū)中的數(shù)據(jù)
}
} else {
//創(chuàng)建Values對(duì)象
values = initializeValues(currentThread);
}
return (T) values.getAfterMiss(this); //從目標(biāo)線程存儲(chǔ)區(qū)沒(méi)有查詢是則返回null
}
ThreadLocal的get()和set()方法操作的類型都是泛型盆繁,接著回到前面提到的sThreadLocal
變量掀淘,其定義如下:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>()
可見(jiàn)sThreadLocal
的get()和set()操作的類型都是Looper
類型。
1.4 Message
1.4.1 消息對(duì)象
每個(gè)消息用Message
表示油昂,Message
主要包含以下內(nèi)容:
數(shù)據(jù)類型 | 成員變量 | 解釋 |
---|---|---|
int | what | 消息類別 |
long | when | 消息觸發(fā)時(shí)間 |
int | arg1 | 參數(shù)1 |
int | arg2 | 參數(shù)2 |
Object | obj | 消息內(nèi)容 |
Handler | target | 消息響應(yīng)方 |
Runnable | callback | 回調(diào)方法 |
創(chuàng)建消息的過(guò)程革娄,就是填充消息的上述內(nèi)容的一項(xiàng)或多項(xiàng)倾贰。
1.4.2 消息池
在代碼中,可能經(jīng)忱雇铮看到recycle()方法匆浙,咋一看,可能是在做虛擬機(jī)的gc()相關(guān)的工作厕妖,其實(shí)不然首尼,這是用于把消息加入到消息池的作用。這樣的好處是言秸,當(dāng)消息池不為空時(shí)软能,可以直接從消息池中獲取Message對(duì)象,而不是直接創(chuàng)建举畸,提高效率查排。
靜態(tài)變量sPool
的數(shù)據(jù)類型為Message,通過(guò)next成員變量俱恶,維護(hù)一個(gè)消息池雹嗦;靜態(tài)變量MAX_POOL_SIZE
代表消息池的可用大小合是;消息池的默認(rèn)大小為50了罪。
消息池常用的操作方法是obtain()和recycle()。
public final Message obtainMessage() {
return Message.obtain(this);
}
obtain()聪全,從消息池取Message泊藕,都是把消息池表頭的Message取走,再把表頭指向next;
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null; //從sPool中取出一個(gè)Message對(duì)象难礼,并消息鏈表斷開(kāi)
m.flags = 0; // 清除in-use flag
sPoolSize--; //消息池的可用大小進(jìn)行減1操作
return m;
}
}
return new Message(); // 當(dāng)消息池為空時(shí)娃圆,直接創(chuàng)建Message對(duì)象
}
recycle
recycle(),將Message加入到消息池的過(guò)程蛾茉,都是把Message加到鏈表的表頭讼呢;
public void recycle() {
if (isInUse()) { //判斷消息是否正在使用
if (gCheckRecycle) { //Android 5.0以后的版本默認(rèn)為true,之前的版本默認(rèn)為false.
throw new IllegalStateException("This message cannot be recycled because it is still in use.");
}
return;
}
recycleUnchecked();
}
//對(duì)于不再使用的消息,加入到消息池
void recycleUnchecked() {
//將消息標(biāo)示位置為IN_USE谦炬,并清空消息所有的參數(shù)悦屏。
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) { //當(dāng)消息池沒(méi)有滿時(shí),將Message對(duì)象加入消息池
next = sPool;
sPool = this;
sPoolSize++; //消息池的可用大小進(jìn)行加1操作
}
}
}
2. 消息隊(duì)列的創(chuàng)建
可以在子線程創(chuàng)建handler么键思?
主線程 Looper 和子線程的 Looper 有什么區(qū)別础爬?
Handler、 Looper 和 MessageQueue有什么關(guān)系吼鳞?
MessageQueue是怎么創(chuàng)建的看蚜?
2.1 Handler構(gòu)造函數(shù)
一個(gè)例子:
new Thread() {
@Override
public void run() {
new Handler();
}
}.start();
//子線程創(chuàng)建Handler 會(huì)拋異常
//java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare
上面的例子中,子線程中創(chuàng)建Handler赔桌,拋異常
源碼分析:
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
//匿名類供炎、內(nèi)部類或本地類都必須申明為static渴逻,否則會(huì)警告可能出現(xiàn)內(nèi)存泄露
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());
}
}
//必須先執(zhí)行Looper.prepare(),才能獲取Looper對(duì)象碱茁,否則為null.
mLooper = Looper.myLooper(); //從當(dāng)前線程的TLS中獲取Looper對(duì)象
//獲取不到mLooper對(duì)象裸卫,拋出異常(必須先調(diào)用Looper.prepare())
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
//消息隊(duì)列,來(lái)自Looper對(duì)象
mQueue = mLooper.mQueue;
mCallback = callback; //回調(diào)方法
mAsynchronous = async; //設(shè)置消息是否為異步處理方式
}
2.2 Looper 對(duì)象的創(chuàng)建和獲取
2.2.1 Looper 創(chuàng)建
Looper.prepare()每個(gè)線程只允許執(zhí)行一次
//對(duì)于無(wú)參的情況纽竣,默認(rèn)調(diào)用 prepare(true),表示這個(gè)Looper允許退出
//prepare(false)茧泪,表示不允許退出
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
//每個(gè)線程只允許執(zhí)行一次該方法蜓氨,第二次執(zhí)行時(shí)線程的TLS已有數(shù)據(jù),則會(huì)拋出異常
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//創(chuàng)建Looper對(duì)象队伟,并保存到當(dāng)前線程的TLS區(qū)域
sThreadLocal.set(new Looper(quitAllowed));
}
與prepare() 功能相近穴吹,該方法主要在ActivityThread類中使用。
public static void prepareMainLooper() {
prepare(false); //設(shè)置不允許退出的Looper
synchronized (Looper.class) {
//將當(dāng)前的Looper保存為主Looper嗜侮,每個(gè)線程只允許執(zhí)行一次港令。
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
2.2.2 Looper 構(gòu)造函數(shù)
private Looper(boolean quitAllowed) {
//創(chuàng)建MessageQueue對(duì)象
mQueue = new MessageQueue(quitAllowed);
//記錄當(dāng)前線程.
mThread = Thread.currentThread();
}
2.3 MessageQueue 對(duì)象的創(chuàng)建
2.3.1 java層
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
//通過(guò)native方法初始化消息隊(duì)列,其中mPtr是供native代碼使用
mPtr = nativeInit();
}
2.3.2 native層調(diào)用過(guò)程
1. android_os_MessageQueue_nativeInit()
android_os_MessageQueue.cpp
static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
//初始化 NativeMessageQueue
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
if (!nativeMessageQueue) {
jniThrowRuntimeException(env, "Unable to allocate native queue");
return 0;
}
//增加引用計(jì)數(shù)
nativeMessageQueue->incStrong(env);
return reinterpret_cast<jlong>(nativeMessageQueue);
}
2. NativeMessageQueue()
class NativeMessageQueue : public MessageQueue, public LooperCallback {
public:
NativeMessageQueue();
virtual ~NativeMessageQueue();
virtual void raiseException(JNIEnv* env, const char* msg, jthrowable exceptionObj);
void pollOnce(JNIEnv* env, jobject obj, int timeoutMillis);
void wake();
void setFileDescriptorEvents(int fd, int events);
virtual int handleEvent(int fd, int events, void* data);
private:
JNIEnv* mPollEnv;
jobject mPollObj;
jthrowable mExceptionObj;
};
NativeMessageQueue::NativeMessageQueue() :
mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {
//功能類比于Java層的Looper.myLooper(); 獲取TLS中的Looper對(duì)象
mLooper = Looper::getForThread();
if (mLooper == NULL) {
//創(chuàng)建native層的Looper
mLooper = new Looper(false);
//功能類比于Java層的ThreadLocal.set(); 保存native層的Looper到TLS
Looper::setForThread(mLooper);
}
}
3. Looper()
Looper::Looper(bool allowNonCallbacks) :
mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
//構(gòu)造喚醒事件的fd
mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s",
strerror(errno));
AutoMutex _l(mLock);
//重建Epoll事件
rebuildEpollLocked();
}
Looper對(duì)象中的mWakeEventFd添加到epoll監(jiān)控锈颗,以及mRequests也添加到epoll的監(jiān)控范圍內(nèi)顷霹。
void Looper::rebuildEpollLocked() {
// Close old epoll instance if we have one.
if (mEpollFd >= 0) {
//關(guān)閉舊的epoll實(shí)例
close(mEpollFd);
}
// Allocate the new epoll instance and register the wake pipe.
mEpollFd = epoll_create(EPOLL_SIZE_HINT);
struct epoll_event eventItem;
//把未使用的數(shù)據(jù)區(qū)域進(jìn)行置0操作
memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
eventItem.events = EPOLLIN;//可讀事件
eventItem.data.fd = mWakeEventFd;
//將喚醒事件(mWakeEventFd)添加到epoll實(shí)例(mEpollFd)
int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
for (size_t i = 0; i < mRequests.size(); i++) {
const Request& request = mRequests.valueAt(i);
struct epoll_event eventItem;
request.initEventItem(&eventItem);
//將request隊(duì)列的事件,分別添加到epoll實(shí)例
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);
if (epollResult < 0) {
ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s",
request.fd, strerror(errno));
}
}
}
3. 消息傳遞機(jī)制
消息是怎么發(fā)送的击吱?
- Handler.sendMessage
消息循環(huán)過(guò)程是怎樣的淋淀?
- Looper.loop
消息是怎么處理的?
- HandlerDispatchMessage
3.1 消息的發(fā)送
Handler.java
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
//SystemClock.uptimeMillis() + delayMillis 當(dāng)前時(shí)間加上需要延遲的時(shí)間
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
該方法通過(guò)設(shè)置消息的觸發(fā)時(shí)間為0覆醇,從而使Message加入到消息隊(duì)列的隊(duì)頭朵纷。
public final boolean sendMessageAtFrontOfQueue(Message msg) {
//Handler初始化的時(shí)候 mQueue = mLooper.mQueue;
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, 0);
}
3.1.1 java層:enqueueMessage
Handler.equeueMessage
handler發(fā)送消息最終都會(huì)調(diào)用該方法
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//設(shè)置處理消息的target為當(dāng)前發(fā)送消息的handler
msg.target = this;
//調(diào)用默認(rèn)構(gòu)造方法 mAsynchronous = false; 默認(rèn)消息非異步
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
MessageQueue.enqueueMessage
boolean enqueueMessage(Message msg, long when) {
// 每一個(gè)普通Message必須有一個(gè)target
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) {
//正在退出時(shí),直接返回
if (mQuitting) {
msg.recycle();
return false;
}
//標(biāo)記msg正在使用中
msg.markInUse();
msg.when = when;
//mMessages為鏈表的頭結(jié)點(diǎn)
Message p = mMessages;
boolean needWake;
//p==null 說(shuō)明當(dāng)前消息隊(duì)列為空
//調(diào)用sendMessageAtFrontOfQueue發(fā)消息時(shí)when==0
//when < p.when 表示新來(lái)的消息比消息隊(duì)列頭部的消息要早
if (p == null || when == 0 || when < p.when) {
//當(dāng)前消息msg放到鏈表的頭結(jié)點(diǎn)
msg.next = p;
mMessages = msg;
needWake = mBlocked; //當(dāng)阻塞時(shí)需要喚醒
} else {
//如果這個(gè)消息不能插入到鏈表的頭結(jié)點(diǎn)永脓,接下來(lái)找一個(gè)合適的位置插進(jìn)去
//將消息按時(shí)間順序插入到MessageQueue袍辞。
//需要喚醒情況:阻塞了 && 此時(shí)消息對(duì)列頭節(jié)點(diǎn)是barrier消息 && 新來(lái)的消息是異步消息
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
//遍歷單鏈表找到新來(lái)消息的合適的位置
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
//新消息未找到合適位置之前,遍歷過(guò)程中發(fā)現(xiàn)異步消息&&需要喚醒時(shí)常摧,needWake設(shè)置為false
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
//找到合適位置插入鏈表中
msg.next = p;
prev.next = msg;
}
//需要喚醒搅吁,進(jìn)入nativeWake流程
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
3.1.2 native層:nativeWake(mPtr)
【1】android_os_MessageQueue_nativeWake()
==> android_os_MessageQueue.cpp
static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->wake(); 【3】
}
【2】NativeMessageQueue::wake()
==> android_os_MessageQueue.cpp
void NativeMessageQueue::wake() {
mLooper->wake(); 【4】
}
【3】Looper::wake()
==> Looper.cpp
void Looper::wake() {
uint64_t inc = 1;
// 向管道m(xù)WakeEventFd寫入字符1
ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
if (nWrite != sizeof(uint64_t)) {
if (errno != EAGAIN) {
ALOGW("Could not write wake signal, errno=%d", errno);
}
}
}
其中TEMP_FAILURE_RETRY
是一個(gè)宏定義, 當(dāng)執(zhí)行write
失敗后排宰,會(huì)不斷重復(fù)執(zhí)行似芝,直到執(zhí)行成功為止。
3.2 消息的循環(huán)
消息循環(huán)的重點(diǎn):
取消息 queue.next()
分發(fā)消息 msg.target.dispatchMessage(msg);
分發(fā)后的Message回收到消息池板甘,以便重復(fù)利用
3.2.1 Looper.loop()
public static void loop() {
final Looper me = myLooper(); //獲取TLS存儲(chǔ)的Looper對(duì)象
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
//獲取Looper對(duì)象中的消息隊(duì)列
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
//確保在權(quán)限檢查時(shí)基于本地進(jìn)程党瓮,而不是調(diào)用進(jìn)程。
final long ident = Binder.clearCallingIdentity();
//進(jìn)入loop的主循環(huán)方法
for (;;) {
//取下一條消息, 可能會(huì)阻塞
Message msg = queue.next();
//msg == null 表示Looper結(jié)束了,直接退出循環(huán)
if (msg == null) {
return;
}
...
try {
//用于分發(fā)Message
msg.target.dispatchMessage(msg);
} finally {
...
}
...
//恢復(fù)調(diào)用者信息
final long newIdent = Binder.clearCallingIdentity();
...
//將Message放入消息池 重置一些狀態(tài)盐类,放入鏈表中
msg.recycleUnchecked();
}
}
3.2.2 java層 : queue.next()
取下一條消息
Message next() {
final long ptr = mPtr;
if (ptr == 0) { //當(dāng)消息循環(huán)已經(jīng)退出寞奸,則直接返回
return null;
}
int pendingIdleHandlerCount = -1;
//初始值設(shè)為0 呛谜,表示立即返回
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
//阻塞操作,當(dāng)?shù)却齨extPollTimeoutMillis時(shí)長(zhǎng)枪萄,或者消息隊(duì)列被喚醒隐岛,都會(huì)返回
//nextPollTimeoutMillis = -1 表示一直阻塞,直到有消息
//第一次調(diào)用時(shí)nextPollTimeoutMillis = 0 不會(huì)阻塞瓷翻,直接返回
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
//從鏈表的頭部取一條消息
Message msg = mMessages;
//如果第一條消息就是屏障聚凹,就往后遍歷,看看有沒(méi)有異步消息
//如果沒(méi)有齐帚,就休眠妒牙,等待別人喚醒
//如果有,就看離這個(gè)消息出發(fā)時(shí)間還有多久对妄,設(shè)置一個(gè)超時(shí)湘今,繼續(xù)休眠
if (msg != null && msg.target == null) {
//當(dāng)查詢到異步消息,則立刻退出循環(huán)
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
//拿到一條有用的消息
if (msg != null) {
//當(dāng)消息觸發(fā)時(shí)間大于當(dāng)前時(shí)間剪菱,則該消息觸發(fā)時(shí)間還沒(méi)到摩瞎,重新設(shè)置超時(shí)時(shí)間
if (now < msg.when) {
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// 獲取一條消息,并返回
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse(); //設(shè)置消息的使用狀態(tài)孝常,即flags |= FLAG_IN_USE
//成功地獲取MessageQueue中的下一條即將要執(zhí)行的消息
return msg;
}
} else {
// msg==null 沒(méi)有消息的時(shí)候旗们,設(shè)置該值為-1,下次循環(huán)時(shí)茫因,會(huì)一直阻塞直到有消息
nextPollTimeoutMillis = -1;
}
//消息正在退出蚪拦,返回null
if (mQuitting) {
dispose();
return null;
}
//當(dāng)消息隊(duì)列為空 msg == null,或者是消息隊(duì)列的第一個(gè)消息還沒(méi)到時(shí)間
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
//獲取IdleHandlers的個(gè)數(shù)
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
//沒(méi)有idle handlers 需要運(yùn)行冻押,則跳出本次循環(huán)
mBlocked = true;
continue;
}
//有需要運(yùn)行的 IdleHandler
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
//只有第一次循環(huán)時(shí)驰贷,會(huì)運(yùn)行idleHandlers,執(zhí)行完成后洛巢,重置pendingIdleHandlerCount為0.
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null;
boolean keep = false;
try {
keep = idler.queueIdle(); //idle時(shí)執(zhí)行的方法
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
//idler.queueIdle() 返回 false, 移除 IdleHandler
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
//重置idle handler個(gè)數(shù)為0括袒,以保證不會(huì)再次重復(fù)運(yùn)行
pendingIdleHandlerCount = 0;
//當(dāng)調(diào)用一個(gè)空閑handler時(shí),給nextPollTimeoutMillis設(shè)為0稿茉,下次循環(huán)無(wú)需等待直接返回
nextPollTimeoutMillis = 0;
}
}
3.2.3 native層:nativePollOnce
代碼路徑
frameworks\base\core\jni\android_os_MessageQueue.cpp
system\core\libutils\Looper.cpp
frameworks\base\core\jni\android_os_MessageQueue.h
system\core\include\utils\Looper.h
【1】android_os_MessageQueue_nativePollOnce()
==> android_os_MessageQueue.cpp
//初次循環(huán)的 timeoutMillis == 0
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, jlong ptr, jint timeoutMillis) {
//先將java層傳遞下來(lái)的mPtr轉(zhuǎn)換為nativeMessageQueue
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}
【2】NativeMessageQueue::pollOnce()
==> android_os_MessageQueue.cpp
void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
mPollEnv = env;
mPollObj = pollObj;
//調(diào)用到Looper->pollOnce(timeoutMillis)
mLooper->pollOnce(timeoutMillis);
mPollObj = NULL;
mPollEnv = NULL;
if (mExceptionObj) {
env->Throw(mExceptionObj);
env->DeleteLocalRef(mExceptionObj);
mExceptionObj = NULL;
}
}
【3】Looper::pollOnce()
==> Looper.h
inline int pollOnce(int timeoutMillis) {
return pollOnce(timeoutMillis, NULL, NULL, NULL);
}
【4】 Looper::pollOnce()
==> Looper.cpp
/**
*- timeoutMillis:超時(shí)時(shí)長(zhǎng)
*- outFd:發(fā)生事件的文件描述符
*- outEvents:當(dāng)前outFd上發(fā)生的事件翔冀,包含以下4類事件
* - EVENT_INPUT 可讀
* - EVENT_OUTPUT 可寫
* - EVENT_ERROR 錯(cuò)誤
* - EVENT_HANGUP 中斷
*- outData:上下文數(shù)據(jù)
*/
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
// 先處理沒(méi)有Callback方法的 Response事件
while (mResponseIndex < mResponses.size()) {
const Response& response = mResponses.itemAt(mResponseIndex++);
int ident = response.request.ident;
if (ident >= 0) { //ident大于0忘衍,則表示沒(méi)有callback, 因?yàn)镻OLL_CALLBACK = -2,
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
if (outFd != NULL) *outFd = fd;
if (outEvents != NULL) *outEvents = events;
if (outData != NULL) *outData = data;
return ident;
}
}
if (result != 0) {
if (outFd != NULL) *outFd = 0;
if (outEvents != NULL) *outEvents = 0;
if (outData != NULL) *outData = NULL;
return result;
}
// 再處理內(nèi)部輪詢
result = pollInner(timeoutMillis); 【5】
}
}
【5】Looper::pollInner()
==> Looper.cpp
pollOnce返回值說(shuō)明:
- POLL_WAKE: 表示由wake()觸發(fā)调榄,即pipe寫端的write事件觸發(fā)趟咆;
- POLL_CALLBACK: 表示某個(gè)被監(jiān)聽(tīng)fd被觸發(fā)。
- POLL_TIMEOUT: 表示等待超時(shí)渺蒿;
- POLL_ERROR:表示等待期間發(fā)生錯(cuò)誤痢士;
int Looper::pollInner(int timeoutMillis) {
...
int result = POLL_WAKE;
mResponses.clear();
mResponseIndex = 0;
mPolling = true; //即將處于idle狀態(tài)
struct epoll_event eventItems[EPOLL_MAX_EVENTS]; //fd最大個(gè)數(shù)為16
//等待事件發(fā)生或者超時(shí),在nativeWake()方法茂装,向管道寫端寫入字符怠蹂,則該方法會(huì)返回善延;
//出錯(cuò)eventCount = -1 超時(shí) eventCount = 0
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
mPolling = false; //不再處于idle狀態(tài)
mLock.lock(); //請(qǐng)求鎖
if (mEpollRebuildRequired) {
mEpollRebuildRequired = false;
rebuildEpollLocked(); // epoll重建,直接跳轉(zhuǎn)Done;
goto Done;
}
// epoll事件個(gè)數(shù)小于0城侧,發(fā)生錯(cuò)誤易遣,直接跳轉(zhuǎn)Done;
if (eventCount < 0) {
if (errno == EINTR) {
goto Done;
}
result = POLL_ERROR;
goto Done;
}
//epoll事件個(gè)數(shù)等于0,發(fā)生超時(shí)嫌佑,直接跳轉(zhuǎn)Done;
if (eventCount == 0) {
result = POLL_TIMEOUT;
goto Done;
}
//循環(huán)遍歷豆茫,處理所有的事件
for (int i = 0; i < eventCount; i++) {
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if (fd == mWakeEventFd) {
if (epollEvents & EPOLLIN) {
//處理這個(gè)事件,即讀事件
awoken(); //已經(jīng)喚醒了屋摇,則讀取并清空管道數(shù)據(jù)
}
} else {
ssize_t requestIndex = mRequests.indexOfKey(fd);
if (requestIndex >= 0) {
int events = 0;
if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
//處理request澜薄,生成對(duì)應(yīng)的reponse對(duì)象,push到響應(yīng)數(shù)組
pushResponse(events, mRequests.valueAt(requestIndex));
}
}
}
Done: ;
//再處理Native的Message摊册,調(diào)用相應(yīng)回調(diào)方法
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now) {
{
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock(); //釋放鎖
handler->handleMessage(message); // 處理消息事件
}
mLock.lock(); //請(qǐng)求鎖
mSendingMessage = false;
result = POLL_CALLBACK; // 發(fā)生回調(diào)
} else {
mNextMessageUptime = messageEnvelope.uptime;
break;
}
}
mLock.unlock(); //釋放鎖
//處理帶有Callback()方法的Response事件,執(zhí)行Reponse相應(yīng)的回調(diào)方法
for (size_t i = 0; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if (response.request.ident == POLL_CALLBACK) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
// 處理請(qǐng)求的回調(diào)方法
int callbackResult = response.request.callback->handleEvent(fd, events, data);
if (callbackResult == 0) {
removeFd(fd, response.request.seq); //移除fd
}
response.request.callback.clear(); //清除reponse引用的回調(diào)方法
result = POLL_CALLBACK; // 發(fā)生回調(diào)
}
}
return result;
}
【6】Looper::awoken()
void Looper::awoken() {
uint64_t counter;
//不斷讀取管道數(shù)據(jù)颊艳,目的就是為了清空管道內(nèi)容
TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));
}
poll小結(jié)
pollInner()方法的處理流程:
- 先調(diào)用epoll_wait()茅特,這是阻塞方法,用于等待事件發(fā)生或者超時(shí)棋枕;
- 對(duì)于epoll_wait()返回白修,當(dāng)且僅當(dāng)以下3種情況出現(xiàn):
- POLL_ERROR,發(fā)生錯(cuò)誤重斑,直接跳轉(zhuǎn)到Done兵睛;
- POLL_TIMEOUT,發(fā)生超時(shí)窥浪,直接跳轉(zhuǎn)到Done祖很;
- 檢測(cè)到管道有事件發(fā)生,則再根據(jù)情況做相應(yīng)處理:
- 如果是管道讀端產(chǎn)生事件漾脂,則直接讀取管道的數(shù)據(jù)假颇;
- 如果是其他事件,則處理request骨稿,生成對(duì)應(yīng)的reponse對(duì)象笨鸡,push到reponse數(shù)組;
- 進(jìn)入Done標(biāo)記位的代碼段:
- 先處理Native的Message坦冠,調(diào)用Native 的Handler來(lái)處理該Message;
- 再處理Response數(shù)組形耗,POLL_CALLBACK類型的事件;
從上面的流程辙浑,可以發(fā)現(xiàn)對(duì)于Request先收集激涤,一并放入reponse數(shù)組,而不是馬上執(zhí)行例衍。真正在Done開(kāi)始執(zhí)行的時(shí)候昔期,是先處理native Message已卸,再處理Request,說(shuō)明native Message的優(yōu)先級(jí)高于Request請(qǐng)求的優(yōu)先級(jí)硼一。
另外pollOnce()方法中累澡,先處理Response數(shù)組中不帶Callback的事件,再調(diào)用了pollInner()方法般贼。
3.3 消息的處理
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//當(dāng)Message存在回調(diào)方法愧哟,回調(diào)msg.callback.run()方法;
handleCallback(msg);
} else {
if (mCallback != null) {
//當(dāng)Handler存在Callback成員變量時(shí)哼蛆,回調(diào)方法handleMessage()蕊梧;
if (mCallback.handleMessage(msg)) {
return;
}
}
//Handler自身的回調(diào)方法handleMessage()
handleMessage(msg);
}
}
public interface Callback {
public boolean handleMessage(Message msg);
}
Handler中使用 post提交: callback = r
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
消息分發(fā)的優(yōu)先級(jí):
- Message的回調(diào)方法:
message.callback.run()
,優(yōu)先級(jí)最高腮介; - Handler的回調(diào)方法:
Handler.mCallback.handleMessage(msg)
肥矢,優(yōu)先級(jí)僅次于1; - Handler的默認(rèn)方法:
Handler.handleMessage(msg)
叠洗,優(yōu)先級(jí)最低甘改。
消息緩存:
為了提供效率,提供了一個(gè)大小為50的Message緩存隊(duì)列灭抑,減少對(duì)象不斷創(chuàng)建與銷毀的過(guò)程
3.4 消息的移除
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
//從消息隊(duì)列的頭部開(kāi)始十艾,移除所有符合條件的消息
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
//移除剩余的符合要求的消息
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
4. 消息的延時(shí)機(jī)制
-
handler 消息延時(shí)機(jī)制是如何實(shí)現(xiàn)的?
消息隊(duì)列按消息觸發(fā)時(shí)間順序排序
-
消息延時(shí)做了什么特殊處理腾节?
設(shè)置epoll_wait 的超時(shí)時(shí)間忘嫉,使其在特定時(shí)間喚醒
是發(fā)送延時(shí),還是消息處理延時(shí)案腺?
-
延時(shí)精度怎么樣庆冕?
精度不高,有可能有些消息的處理比較耗時(shí)
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) {
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//設(shè)置處理消息的target為當(dāng)前發(fā)送消息的handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
接下來(lái)的分析可以看 3. 消息傳遞機(jī)制-消息的發(fā)送
5. IdleHandler
App啟動(dòng)優(yōu)化涉及到
了解IdleHandler 的作用以及調(diào)用方式
了解IdleHandler 有哪些使用場(chǎng)景
熟悉IdleHandler 的實(shí)現(xiàn)原理
5.1 IdleHandler原理
MessageQueue.java
/**
* Callback interface for discovering when a thread is going to block
* waiting for more messages.
*/
public static interface IdleHandler {
/**
* Called when the message queue has run out of messages and will now
* wait for more. Return true to keep your idle handler active, false
* to have it removed. This may be called if there are still messages
* pending in the queue, but they are all scheduled to be dispatched
* after the current time.
*/
boolean queueIdle();
}
Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() {
//true false 區(qū)別
return false;
}
});
/**
* Add a new {@link IdleHandler} to this message queue. This may be
* removed automatically for you by returning false from
* {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
* invoked, or explicitly removing it with {@link #removeIdleHandler}.
*
* <p>This method is safe to call from any thread.
*
* @param handler The IdleHandler to be added.
*/
public void addIdleHandler(@NonNull IdleHandler handler) {
if (handler == null) {
throw new NullPointerException("Can't add a null IdleHandler");
}
synchronized (this) {
mIdleHandlers.add(handler);
}
}
Message next() {
...
for (;;) {
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
...
// 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.
//看消息列表是否有消息可以分發(fā)救湖,如果有愧杯,就返回該消息
//走到這里說(shuō)明,沒(méi)有消息可以分發(fā)鞋既,下一個(gè)for循環(huán)就要進(jìn)入休眠了
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
// Run the idle handlers.
// We only ever reach this code block during the first iteration.
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);
}
//如果keep == flase 需要remove掉 idler
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
// Reset the idle handler count to 0 so we do not run them again.
pendingIdleHandlerCount = 0;
// While calling an idle handler, a new message could have been delivered
// so go back and look again for a pending message without waiting.
nextPollTimeoutMillis = 0;
}
}
5.2 IdleHandler 在Framework中的使用
void scheduleGcIdler() {
if (!mGcIdleScheduled) {
mGcIdleScheduled = true;
Looper.myQueue().addIdleHandler(mGcIdler);
}
mH.removeMessage(H.GC_WHEN_IDLE);
}
final class GcIdler implements MessageQueue.IdleHandler{
@Override
public boolean queueIdle() {
//實(shí)際上調(diào)用BinderInternal.forceGc("bg");
doGcIfNeeded();
return false;
}
}
一個(gè)例子:等待線程 idle 觸發(fā)回調(diào)
public void waitForIdle(Runnable recipient) {
mMessageQueue.addIdleHandler(new Idler(recipient));
mThread.getHandler().post(new EmptyRunnable());
}
private static final class Idler implements MessageQueueIdleHandler{
public final boolean queueIdle() {
if (mCallback != null) {
mCallback.run();
}
//返回false 表示回調(diào)是一次性的
return false;
}
}
5.3 使用場(chǎng)景
- 延時(shí)執(zhí)行
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//執(zhí)行一些耗時(shí)任務(wù)力九,但是要延時(shí)多久呢?
//可以寫一個(gè)IdleHandler 在主線程空閑的時(shí)候執(zhí)行耗時(shí)任務(wù)邑闺,return false
doSomething();
}
}, 1000);
}
- 批量任務(wù)
任務(wù)密集
只關(guān)注最終結(jié)果
開(kāi)一個(gè)工作線程跌前,每一個(gè)任務(wù)都封裝成一個(gè)消息,丟到工作線程中陡舅。等工作線程空閑下來(lái)之后抵乓,匯總消息,刷新界面
6. 主線程進(jìn)入Looper為什么沒(méi)有ANR
- 了解ANR觸發(fā)的原理
- 了解應(yīng)用的啟動(dòng)流程
- 了解線程的消息循環(huán)機(jī)制
- 了解應(yīng)用和系統(tǒng)服務(wù)通信的過(guò)程
ANR是什么
AMS中 在SystemServer進(jìn)程
final void appNotResponding() {
Message msg = Message.obtain();
msg.what = SHOW_NOT_RESPONDING_MSG;
...
//mUiHandler 是 SystemServer的一個(gè)子線程
mUiHandler.sendMessage(msg);
}
Dialog d = new AppNotResbondingDialog(...);
d.show();
ANR場(chǎng)景:
- Service Timeout
- BroadcastQueue Timeout
- ContentProvider Timeout
- InputDispatching Timeout
以service為例,看看ANR如何觸發(fā)
void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) {
...
bumpServiceExecutingLocked(r, execInFg, "create");
app.thread.scheduleCreateService(r, ...)
}
void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
...
//啟動(dòng)一個(gè)超時(shí)機(jī)制灾炭,如果應(yīng)用端沒(méi)有在規(guī)定時(shí)間啟動(dòng)一個(gè) Service 茎芋,就會(huì)ANR
scheduleServiceTimeoutLocked(r.app);
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
long now = SystemClock.uptimeMillis();
Message msg = mAm.mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
mAm.mHandler.sendMessageAtTime(msg, now + SERVICE_TIMEOUT);
}
void serviceTimeout(ProcessRecord proc) {
...
mAm.appNotResponding(...);
}
應(yīng)用端收到系統(tǒng)服務(wù)發(fā)過(guò)來(lái)的啟動(dòng) service 服務(wù)之后
private void handleCreateService(CreateServiceData data) {
service = (Service)cl.loadClass(data.info.name).newInstance();
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(...);
service.onCreate();
ActivityManagerNative.getDefault().serviceDoneExecuting(...);
}
//跨進(jìn)程調(diào)用
private void serviceDoneExecutingLocked(ServiceRecord r, ...) {
mAm.mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
}
- anr 是應(yīng)用沒(méi)有在規(guī)定的時(shí)間內(nèi)完成AMS指定的任務(wù)導(dǎo)致的
- AMS請(qǐng)求調(diào)到應(yīng)用端Binder線程,再丟消息去喚醒主線程來(lái)處理
- ANR不是因?yàn)橹骶€程loop循環(huán)蜈出,而是因?yàn)橹骶€程中有耗時(shí)任務(wù)
7. 消息屏障
消息有三種 :
normal
barrier
async
怎么往消息隊(duì)列發(fā)送消息屏障田弥?
postSyncBarrier只對(duì)同步消息產(chǎn)生影響,對(duì)于異步消息沒(méi)有任何差別
private int postSyncBarrier(long when) {
synchronized(this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
//沒(méi)有target 不需要分發(fā)铡原,可以根據(jù)target是否為null 判斷是否是消息屏障
msg.makeInUse();
msg.when = when;
msg.arg1 = token;
//給這個(gè)msg按時(shí)間順序插到消息隊(duì)列
return token;
}
}
消息屏障只會(huì)影響它后面的消息偷厦,它前面的消息不受影響
消息隊(duì)列可以插入多個(gè)消息屏障
消息屏障插到消息隊(duì)列沒(méi)有喚醒線程
插入消息屏障會(huì)返回一個(gè) token(屏障的一個(gè)序列號(hào)) 憑借這個(gè)token在消息隊(duì)列中查找消息屏障,然后移除它
只能通過(guò)反射調(diào)用 postSyncBarrier
刪除屏障
public void removeSyncBarrier(int token) {
synchronized (this) {
Message prev = null;
Message p = mMessages;
//從消息隊(duì)列找到 target為空,并且token相等的Message
while (p != null && (p.target != null || p.arg1 != token)) {
prev = p;
p = p.next;
}
final boolean needWake;
if (prev != null) {
prev.next = p.next;
needWake = false;
} else {
mMessages = p.next;
needWake = mMessages == null || mMessages.target != null;
}
p.recycleUnchecked();
//如果這個(gè)線程就是因?yàn)檫@個(gè)屏障block住燕刻,那么撤除屏障之后只泼,需要喚醒線程
if (needWake && !mQuitting) {
nativeWake(mPtr);
}
}
}