接觸android也有一段時間了,說實話真的感覺google很偉大,用那麼基礎的技術卻做出那麼神秘的東西,也同時為google提出“隨時隨地為你提供資訊!”而感動,當然這都是我個人的真實感受,還是開始本文吧。
在android開發中處理耗時的工作一般都推薦AsyncTask,這個我也確實喜歡,但是我最先接觸的確實Handler,而且直到今天我也沒有徹底搞清楚,凡事不能總是逃避,只有一次性的解決才能安心,那就從handler開始吧:
handler發送Message :
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
上面是Handler類的sendMessage方法,這裡他調用了另一個方法,繼續追蹤:
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)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
此方法執行後Message入隊了。
Handler類中的操作暫時告一段落,Looper在主線程裡面等不及了。
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
//if (!me.mRun) {
// break;
//}
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}
從訊息佇列裡面拿出訊息,注意這一步 msg.target.dispatchMessage(msg); 還記得 Handler中sendMessageAtTime()方法裡面的這行代碼吧, msg.target = this; 這裡調用的dispatchMessage是剛才那個發送訊息的Handler,OK,再回到Handler類中看看dispatchMessage()到底是什麼東東。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
上面的if判斷先白不用看,這個是處理Runnbale的,直接看看這個handleMessage(msg);哈哈,終於看見我們所熟悉的方法了,Handler中這個方法是構造方法,到這裡你應該明白了對於Message的處理了吧。
在看看對於Runnable的處理,先去看看handler的post()方法:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
接著追..
private final Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
注意這行 m.callback = r; 我們一開始post()進來的Runnable到這裡了,被賦值到Message的callback屬性上了,直接把這個帶有特殊屬性的Message放入隊列了。
然後Looper處理後回調到我們的handler類裡面的此方法:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
現在這裡的if判斷對我們來說已經有意義了。
if (msg.callback != null) {
handleCallback(msg);
}
這裡msg.callback當然不為null,那就執行 handleCallback(msg);吧,
private final void handleCallback(Message message) {
message.callback.run();
}
我靠,直接調用run()方法。
這裡大致摸清了整個過程。
其實我只是想說的是對於簡單的耗時操作沒必要用AsyncTask,不然就泛濫了。