當程式執行時,會先執行activitythread
的main
方法。會執行looper.preparemainlooper()
方法和looper.loop()
方法。
looper.preparemainlooper()
public
static
void
preparemainlooper()
smainlooper =
mylooper()
;}}
其中又會進入prepare
方法中,會發現呼叫了sthreadlocal.set(new looper(quitallowed));
其中通過new looper()
方法
private
looper
(boolean quitallowed)
對messagequeue佇列進行了初始化。
set方法:
public
void
set(t value)
將當前主線程新增到sthreadlocal中。通過static final threadlocalsthreadlocal = new threadlocal()
設定靜態實現保證其唯一性。
looper.loop()
final looper me =
mylooper()
;if(me == null)
final messagequeue queue = me.mqueue;
首先通過mylooper()
方法,
public
static
@nullable looper mylooper()
拿到存入的主線程的looper物件值,然後再拿到messagequeue物件,
其中
for(;
;)finally}.
....
.}
我們可以發現通過queue.next()
拿到佇列中先進先出的值,使用msg.target.dispatchmessage(msg);
進行分發,其中msg.target為handler(在message類中我們可以找到handler target
的定義)。
我們在子執行緒中通過handler1.sendmessagedelayed(message,3000);
進行傳送資料,最後都會呼叫到handler中的sendmessageattime()
方法,
public
boolean
sendmessageattime
(message msg,
long uptimemillis)
return
enqueuemessage
(queue, msg, uptimemillis)
;}
然後呼叫enqueuemessage()
方法,
private
boolean
enqueuemessage
(messagequeue queue, message msg,
long uptimemillis)
return queue.
enqueuemessage
(msg, uptimemillis)
;}
在此方法中對message的target屬性進行了賦值。
然後通過messagequeue類queue.enqueuemessage(msg, uptimemillis)
進行佇列的填充。
其中主要**為:
message p = mmessages;
boolean needwake;
if(p == null || when ==
0|| when < p.when)
else
if(needwake && p.
isasynchronous()
)}msg.next = p;
// invariant: p == prev.next
prev.next = msg;
}
將定義的全域性的mmessages
拿到,進行非空判定,若為空則直接新增到佇列首位。不為空,則通過鍊錶的方式,將當前傳送的message物件新增到佇列的尾部。實現資料的填充佇列處理。
從looper.loop()
的原始碼中可以看到,在程式啟動時,在主線程中loop()方法的for (;;)
進行無限迴圈,通過message msg = queue.next()
取得佇列中的首位message訊息物件,然後通過handler的msg.target.dispatchmessage(msg)
進行分發處理。
public
void
dispatchmessage
(message msg)
else
}handlemessage
(msg);}
}
其中此時msg.callback為null,則進入
if
(mcallback != null)
}handlemessage
(msg)
;
然後在我們的activity中重寫
private handler handler1 =
newhandler
(new
handler.callback()
});
或者
private handler handler2 =
newhandler()
};
來進行主線程中處理資料更新。
子執行緒中handler1.post()或者runonuithread可以更新ui的原因
其中runonuithread方法為
public
final
void
runonuithread
(runnable action)
else
}
同樣呼叫handler的post方法。
然後進入
public
final
boolean
post
(runnable r)
呼叫sendmessagedelayed
方法時,引數getpostmessage(r)
為將post的runnable方法賦值給message。
private
static message getpostmessage
(runnable r)
其中message的callback屬性為runnable。然後同樣呼叫到enqueuemessage()
方法中,然後通過主線程中loop.loop()的無限迴圈將其拿到,呼叫dispatchmessage
方法,
public
void
dispatchmessage
(message msg)
else
}handlemessage
(msg);}
}
此時msg.callback將不為null,將會進入handlecallback(msg);
中,執行
private
static
void
handlecallback
(message message)
run()方法進行主線程更新操作。 handler原始碼分析
昨天研究了一下handler的原始碼,今天總結一下 android只有乙個執行緒可以操作ui介面,我們稱之為ui執行緒。每個ui執行緒都維護乙個looper,這個looper中有乙個messagequeue來儲存ui乙個訊息佇列。通過控制這個訊息佇列來實現對ui介面的順序重新整理。handler.s...
Handler通訊 原始碼分析
1.messagequeue 訊息佇列 執行緒中更新 ui 的時候經常是呼叫 sendmessage 和 sendmessagedelayed 這樣 我跟蹤 進入到 handler 的 sendmessage 方法 public final boolean sendmessage message m...
Handler原始碼解析
意思就是說 在沒有呼叫looper.prepare 之前不能在子執行緒建立handler。為什麼在主線程中我們就已經可以直接建立handler?因為在activity的啟動 中,已經在當前ui執行緒 主線程 呼叫了looper.preparemainlooper 和looper.loop 方法。我們...