由于在UI線程中不能做耗時(shí)長(zhǎng)的操作,所以系統(tǒng)提供了Handler和AsyncTask來(lái)進(jìn)行異步消息處理和任務(wù)联四;
異步消息處理機(jī)制Handler
Android中的異步消息處理主要由四個(gè)部分組成沃缘,Message篮奄、Handler黍檩、MessageQueue和Looper估蹄。
Message
Message是在線程之間傳遞的消息颂碧,它可以在內(nèi)部攜帶少量的信息荠列,用于在不同線程之間交換數(shù)據(jù)。
Handler
Handler顧名思義也就是處理者的意思载城,它主要是用于發(fā)送和處理消息的肌似。發(fā)送消息一般是使用Handler的sendMessage()或者post()方法,而發(fā)出的消息經(jīng)過(guò)一系列地輾轉(zhuǎn)處理后诉瓦,最終會(huì)傳遞到Handler的handleMessage()方法中川队。
MessageQueue
MessageQueue是消息隊(duì)列的意思,它主要是用于存放所有的Handler發(fā)送的消息睬澡。這部分消息會(huì)一直存在于消息隊(duì)列中呼寸,等待被處理。每個(gè)線程中只有一個(gè)MessageQueue對(duì)象猴贰。
Looper
Looper調(diào)用Looper的loop()方法后对雪,就會(huì)進(jìn)入到一個(gè)無(wú)限循環(huán)當(dāng)中,然后每當(dāng)發(fā)現(xiàn)MessageQueue中存在一條消息米绕,就會(huì)將它取出瑟捣,并傳遞到Handler的handleMessage()方法中。每個(gè)線程中也只會(huì)有一個(gè)Looper對(duì)象栅干。
Handler源碼分析:
Handler的構(gòu)造函數(shù)
Handler的定義屬性:
finalMessageQueuemQueue;
finalLoopermLooper;
finalCallbackmCallback;
finalbooleanmAsynchronous;
IMessengermMessenger;
在Handler中定義了7個(gè)構(gòu)造函數(shù),分別是:Handler()迈套、Handler(Callback callback)、Handler(Looper
looper)碱鳞、Handler(Looper looper, Callback callback)桑李、Handler(boolean
async)、Handler(Callback callback, boolean async)、Handler(Looper
looper, Callback callback, boolean async)贵白;在上面我們已經(jīng)說(shuō)過(guò)Handler異步消息機(jī)制主要包含MessageQueue率拒、Looper和Message三個(gè)部分,那么首先要分析的這三個(gè)屬性怎么賦值禁荒;
構(gòu)造方法一:
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;//在Looper中進(jìn)行分析
mCallback = callback;
mAsynchronous = async;
}
構(gòu)造方法二:
publicHandler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class 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());
}
}暫時(shí)不管
mLooper = Looper.myLooper();//在looper中分享
if (mLooper == null) {
throw new RuntimeException(
"Can't create handlerinside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
下面看下我們?cè)谑褂肏andler是常用的空參構(gòu)造函數(shù)的調(diào)用
public Handler() {
this(null, false);//調(diào)用Handler(Callback callback, booleanasync)
}
可以看到最終會(huì)在構(gòu)造函數(shù)中進(jìn)行對(duì)mLooper和mQueue的賦值猬膨;
Handler消息初始化
在Handler中對(duì)消息的初始化主要是重載了5個(gè)obtainMessage()方法;分別是
publicfinalMessageobtainMessage()
{
returnMessage.obtain(this);
}
publicfinalMessageobtainMessage(intwhat)
{
returnMessage.obtain(this, what);
}
publicfinalMessageobtainMessage(intwhat, Object obj)
{
returnMessage.obtain(this, what,obj);
}
publicfinalMessageobtainMessage(intwhat,intarg1,intarg2)
{
returnMessage.obtain(this, what,arg1, arg2);
}
publicfinalMessageobtainMessage(intwhat,intarg1,intarg2, Object obj)
{
returnMessage.obtain(this, what,arg1, arg2, obj);
}
可以看到在創(chuàng)建消息Message時(shí)會(huì)傳進(jìn)去一個(gè)參數(shù)this即當(dāng)前Handler呛伴,這點(diǎn)很重要勃痴,我們知道在消息處理時(shí)要找到對(duì)應(yīng)的處理消息的Handler;
Handler中的send方法
當(dāng)handler在分線程進(jìn)行完耗時(shí)的操作后并完成消息創(chuàng)建及配置热康,那么下面就進(jìn)消息的發(fā)送沛申;在handler中主要有:
空消息:
sendEmptyMessage(int what)
sendEmptyMessageDelayed(int what, long
delayMillis)
sendEmptyMessageAtTime(int what, long
uptimeMillis)
非空消息:
sendMessage(Message
msg)發(fā)送一個(gè)普通的消息。即延時(shí)為零的消息姐军;’
sendMessageDelayed(Message
msg, long delayMillis)發(fā)送一個(gè)延時(shí)消息铁材;
sendMessageAtFrontOfQueue(Message
msg);
sendMessageAtTime(Message
msg, long uptimeMillis)庶弃;
上述方法最終會(huì)調(diào)用Handler中的enqueueMessage(MessageQueue
queue, Message msg, long uptimeMillis)方法衫贬,enqueueMessage()又會(huì)調(diào)用MessageQueue的enqueueMessage(msg,
uptimeMillis)方法,最終將消息send到消息隊(duì)列中歇攻;
Handler中的Post方法
在Hanlder中處理定義了對(duì)消息的send方法之外固惯,還定義了針對(duì)Runnable的post方法;相關(guān)方法:
post(Runnable r)調(diào)用方法sendMessageDelayed(getPostMessage(r),
0);
postAtTime(Runnable r, long uptimeMillis)調(diào)用sendMessageAtTime(getPostMessage(r),
uptimeMillis);
postAtTime(Runnable r, Object token, long
uptimeMillis) sendMessageAtTime(getPostMessage(r, token),
uptimeMillis);sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
postDelayed(Runnable r, long delayMillis)調(diào)用sendMessageDelayed(getPostMessage(r),
delayMillis);
postAtFrontOfQueue(Runnable r)調(diào)用sendMessageAtFrontOfQueue(getPostMessage(r));
可以發(fā)現(xiàn)Handler的post方法最終是調(diào)用了相關(guān)send方法缴守,但是所有的post方法同時(shí)調(diào)用的一個(gè)getPostMessage(r)來(lái)對(duì)消息的創(chuàng)建葬毫;實(shí)現(xiàn)如下
privatestaticMessagegetPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
returnm;
}
可以看到在該方法中主要是通過(guò)將Runnable復(fù)制給m.callback來(lái)實(shí)現(xiàn);這將在對(duì)消息的分析是詳細(xì)介紹屡穗;
Handler中的消息處理過(guò)程
我們知道贴捡,Handler消息機(jī)制中只要消息隊(duì)列中存在消息,那么looper就不停的取出去消息并且將其交給Handler進(jìn)行處理村砂。這里我們暫時(shí)不關(guān)注looper是如何取出消息及分配消息烂斋,我們只關(guān)注消息是如何處理的;在Handler中對(duì)消息的處理只要一個(gè)方法:
publicvoiddispatchMessage(Message msg) {
if(msg.callback !=null) {
handleCallback(msg);
}else{
if(mCallback!=null){
if(mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
在該方法中首先要判斷msg.callback !=null础废,而在上面我們已經(jīng)分析過(guò)了只有在使用post相關(guān)的方法時(shí)msg.callback會(huì)被賦值汛骂;當(dāng)msg.callback !=null時(shí)會(huì)調(diào)用handleCallback(msg):privatestaticvoidhandleCallback(Message message) {
message.callback.run();//即調(diào)用Runable的run方法
}
當(dāng)msg.callback==null時(shí)首先要判斷的時(shí)mCallback!=null;在這里說(shuō)明一下什么是mCallback:在Handler中定義這樣的一個(gè)final屬性:final Callback mCallback评腺,那么什么是Callback呢帘瞭?
publicinterfaceCallback {
public boolean handleMessage(Messagemsg);
}
在Handler中定義這樣一個(gè)接口,官方的定義是:
Callback interface you can use when
instantiating a Handler to avoid having to implement your own subclass of
Handler.
當(dāng)mCallback!=null不為空時(shí)蒿讥,如果public boolean handleMessage(Message
msg)方法返回的true蝶念,那么表示當(dāng)前的message被處理抛腕,return;如果放回的絲false媒殉,那么在執(zhí)行完public boolean handleMessage(Message
msg)方法后會(huì)繼續(xù)執(zhí)行handleMessage(msg)方法担敌,完成對(duì)數(shù)據(jù)的處理;
Handler中的消息撤回和消息隊(duì)列的判斷
Handler中定義的消息撤回的方法:
removeMessages(int what)根據(jù)what來(lái)撤回消息适袜;
removeMessages(int what, Object object)根據(jù)what和object來(lái)撤回消息柄错;
removeCallbacksAndMessages(Object token)根據(jù)token撤回message和callbacks舷夺,當(dāng)token是null是撤回消息隊(duì)列的所有消息苦酱;
同時(shí),handler中還定義了對(duì)消息隊(duì)列進(jìn)行查詢的方法:
hasMessages(int what)
hasMessages(int what, Object object)
hasCallbacks(Runnable r)
Looper的實(shí)現(xiàn)
我們都知道handler的主要的任務(wù)就是進(jìn)行線程間的通信给猾,實(shí)現(xiàn)分線程和UI線程通信界面更新疫萤,但是我們發(fā)現(xiàn)在整個(gè)的handler中沒(méi)有關(guān)于UI線程相關(guān)的東西;那么下面我們繼續(xù)分析looper敢伸,希望能夠找到著相關(guān)的東西扯饶;和Handler分析過(guò)程一樣,我們首先看一下looper的構(gòu)造函數(shù)和定義的屬性:
Looper定義的相關(guān)的熟悉如下
staticfinalThreadLocalsThreadLocal=newThreadLocal();
privatestaticLoopersMainLooper;// guarded by Looper.class
finalMessageQueuemQueue;
finalThreadmThread;
然后查找Looper的構(gòu)造函數(shù)池颈,結(jié)果發(fā)現(xiàn)了:
privateLooper(booleanquitAllowed) {
mQueue=newMessageQueue(quitAllowed);//在消息隊(duì)列中分析
mThread= Thread.currentThread();
}
私有的構(gòu)造函數(shù)尾序,有一種單例的感覺(jué);接著卻找到了這樣一個(gè)方法prepare()躯砰,
publicstaticvoidprepare(){
prepare(true);
}
和
privatestaticvoidprepare(booleanquitAllowed) {
if(sThreadLocal.get() !=null) {
thrownewRuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(newLooper(quitAllowed));
}
可以new Looper的每币,接著分析,什么是sThreadLocal琢歇,找到ThreadLocal中的set和get方法兰怠,其中set()的作用是Sets the value of this variable for the
current thread,即將looper與sThreadLocal當(dāng)前線程綁定李茫;通過(guò)prepare克可以創(chuàng)建looper揭保,同時(shí)Looper中還定義了myLooper()方法獲取當(dāng)前線程的looper;
publicstaticLoopermyLooper() {
returnsThreadLocal.get();
}
接下來(lái)就該從消息隊(duì)列中獲取消息了魄宏,即調(diào)用loop()方法秸侣;
publicstaticvoidloop() {
final Looper me = myLooper();
finalMessageQueue queue = me.mQueue;
…..
for(;;) {
Message msg = queue.next();// might block
if(msg ==null) {
// No message indicates that the
message queue is quitting.
return;
}
……
msg.target.dispatchMessage(msg);
……
}
}
主要是通過(guò)一個(gè)死循環(huán)不停的從消息隊(duì)列中取出消息,然后執(zhí)行msg.target.dispatchMessage(msg)方法即handler. dispatchMessage(msg)方法宠互,由handler去完成消息的處理味榛;
同時(shí),除了消息的獲取之外名秀,Looper還定義了兩個(gè)退出的方法quit()和quitSafely()励负;這兩個(gè)方法都調(diào)用了Messagequeue的quit()方法,匕得,這兩個(gè)方法的區(qū)別會(huì)在下面解析
Messagequeue時(shí)進(jìn)行說(shuō)明
publicvoidquit() {
mQueue.quit(false);
}
publicvoidquitSafely() {
mQueue.quit(true);
}
主線程Looper的問(wèn)題继榆,我們?cè)赨I使用Handler進(jìn)行線程通信時(shí)沒(méi)有手動(dòng)的創(chuàng)建Loop而是由于主線的looper系統(tǒng)已經(jīng)為我們創(chuàng)建好巾表;
消息隊(duì)列的實(shí)現(xiàn)
老規(guī)矩首先分析一下MessageQueue的構(gòu)造函數(shù),發(fā)現(xiàn)
// True if the message queue can be quit.
privatefinalbooleanmQuitAllowed;
MessageQueue(booleanquitAllowed) {
mQuitAllowed= quitAllowed;
mPtr=nativeInit();
}
結(jié)合MessageQueue和Looper的構(gòu)造函數(shù)和prepare()方法略吨,我們可以知道我們自己創(chuàng)建的MessageQueue都是可以quit集币,但是在Looper中還定義這么一個(gè)方法:
publicstaticvoidprepareMainLooper(){
prepare(false);//這個(gè)地方為false;
synchronized(Looper.class) {
if(sMainLooper!=null) {
thrownewIllegalStateException("The main Looper has already been prepared.");
}
sMainLooper=myLooper();
}
}
下面分析一下MessageQueue的enqueueMessage()方法和next()翠忠;
booleanenqueueMessage(Message msg,longwhen) {
…….
msg.when = when;
Message p =mMessages;
booleanneedWake;
if(p ==null|| when == 0 || when
//
New head, wake up the event queue if blocked.
msg.next = p;
mMessages= msg;
needWake =mBlocked;
}
else
{
needWake =mBlocked&& p.target ==null&& msg.isAsynchronous();
Message prev;
for(;;) {
prev = p;
p = p.next;
if(p ==null|| when < p.when) {
break;
}
if(needWake && p.isAsynchronous()) {
needWake =false;
}
}
msg.next = p;// invariant: p == prev.next
prev.next = msg;
}
if(needWake) {
nativeWake(mPtr);
}
}
returntrue;
}
消息隊(duì)列消息的添加主要是進(jìn)行相應(yīng)的判斷并且循環(huán)整個(gè)消息隊(duì)列來(lái)進(jìn)行按照時(shí)間的插入鞠苟;
Message next() {
intpendingIdleHandlerCount = -1;// -1 only during
first iteration
intnextPollTimeoutMillis = 0;
for(;;) {
if(nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
// We
can assume mPtr != 0 because the loop is obviously still running.
// The
looper will not call this method after the loop quits.
nativePollOnce(mPtr, nextPollTimeoutMillis);
synchronized(this) {
//Try to retrieve the next message.Returnif found.
finallongnow = SystemClock.uptimeMillis();
Message prevMsg =null;
Message msg =mMessages;
if(msg !=null&& msg.target ==null) {
//Stalled by a barrier.Find the nextasynchronous message in the queue.
do{
prevMsg = msg;
msg = msg.next;
}while(msg !=null&& !msg.isAsynchronous());
}
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;
}else{
mMessages= msg.next;
}
msg.next =null;
if(false)Log.v("MessageQueue","Returning message: "+ msg);
msg.markInUse();
returnmsg;
}
}else{
//
No more messages.
nextPollTimeoutMillis = -1;
}
//
Process the quit message now that all pending messages have been handled.
if(mQuitting) {
dispose();
returnnull;
}
if(pendingIdleHandlerCount < 0
&& (mMessages==null|| now
pendingIdleHandlerCount =mIdleHandlers.size();
}
if(pendingIdleHandlerCount <= 0) {
mBlocked=true;
continue;
}
if(mPendingIdleHandlers==null) {
mPendingIdleHandlers=newIdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers=mIdleHandlers.toArray(mPendingIdleHandlers);
}
for(inti = 0; i
finalIdleHandleridler =mPendingIdleHandlers[i];
mPendingIdleHandlers[i]=null;//
release the reference to the handler
booleankeep =false;
try{
keep = idler.queueIdle();
}catch(Throwable t) {
Log.wtf("MessageQueue","IdleHandler threw exception", t);
}
if(!keep) {
synchronized(this) {
mIdleHandlers.remove(idler);
}
}
}
pendingIdleHandlerCount = 0;
nextPollTimeoutMillis = 0;
}
}
voidquit(booleansafe) {
if(!mQuitAllowed) {
thrownewRuntimeException("Main thread not allowed to quit.");
}//主線程不可退出
synchronized(this) {
if(mQuitting) {
return;
}
mQuitting=true;
if(safe) {
removeAllFutureMessagesLocked();//處理完所有的消息后提出
}else{
removeAllMessagesLocked();//直接退出,不再關(guān)注消息隊(duì)列是否處理完
}
// We
can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
Message的實(shí)現(xiàn)
對(duì)于message的分析秽之,主要是關(guān)注兩點(diǎn)
Handlertarget;
Runnablecallback;
Message的創(chuàng)建主要是調(diào)用了其靜態(tài)方法obtain():
* Return a newMessage instance from the global pool. Allows us to
avoidallocating new objects in many cases.
publicstaticMessageobtain() {
synchronized(sPoolSync) {
if(sPool!=null){
Message m =sPool;
sPool= m.next;
m.next=null;
sPoolSize--;
returnm;
}
}
returnnewMessage();
}
從整個(gè)Messge池中返回一個(gè)新的Message實(shí)例当娱,在許多情況下使用它,因?yàn)樗鼙苊夥峙湫碌膶?duì)象
在上面我們已經(jīng)知道在handler進(jìn)行消息初始化的時(shí)候會(huì)調(diào)用obtain(Handler h)等方法其最終會(huì)通過(guò)obtain()進(jìn)行消息返回并且對(duì)消息的target進(jìn)行賦值考榨;這也就是是在Loop()方法中進(jìn)行消息分配的原因跨细;Handler中的其他消息的初始化大家可以自己對(duì)應(yīng)源碼去看一下;
我們?cè)贖andler的分配的時(shí)候曾經(jīng)有過(guò)這樣一個(gè)判斷
if(msg.callback !=null) {
handleCallback(msg);
}
下面我們看一下msg.callback河质,在消息初始化的時(shí)候冀惭,當(dāng)我們傳入一個(gè)Runnable時(shí),
callback
Runnable that will execute when the message is handled.也就是說(shuō)再消息發(fā)送出去后會(huì)在執(zhí)行掀鹅。
publicstaticMessageobtain(Handler h, Runnable callback) {
Message m =obtain();
m.target= h;
m.callback= callback;
returnm;
}