安卓中的Handle是一個(gè)非常重要的類,它主要用于處理消息和線程之間的通信。在本篇博客中,我們將對(duì)安卓中的Handle源碼進(jìn)行分析,希望能夠幫助讀者更好地理解這個(gè)類的實(shí)現(xiàn)原理。
首先,我們來(lái)看一下Handle的構(gòu)造函數(shù):
public Handle() {
this(null, false);
}
可以看到,Handle的構(gòu)造函數(shù)并沒有做太多的事情,只是簡(jiǎn)單地調(diào)用了另一個(gè)構(gòu)造函數(shù),并傳入了兩個(gè)參數(shù):null和false。
接下來(lái),我們來(lái)看一下另一個(gè)構(gòu)造函數(shù):
public Handle(Callback callback, boolean async) {
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create Handle inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
可以看到,在這個(gè)構(gòu)造函數(shù)中,Handle首先獲取了當(dāng)前線程的Looper對(duì)象,如果當(dāng)前線程沒有Looper對(duì)象,則會(huì)拋出一個(gè)RuntimeException異常。接著,Handle將這個(gè)Looper對(duì)象中的消息隊(duì)列賦值給了Handle的mQueue變量。然后,Handle還保存了一個(gè)回調(diào)接口對(duì)象mCallback和一個(gè)標(biāo)志位mAsynchronous。
接下來(lái),我們來(lái)看一下Handle中最重要的方法之一,sendMessage()方法:
public final boolean sendMessage(Message msg) {
return sendMessageDelayed(msg, 0);
}
public 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) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Handle", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
可以看到,sendMessage()方法實(shí)際上是調(diào)用了sendMessageDelayed()方法,并將delayMillis參數(shù)設(shè)置為0。sendMessageDelayed()方法中,Handle會(huì)根據(jù)delayMillis參數(shù)計(jì)算出消息的到達(dá)時(shí)間,然后調(diào)用sendMessageAtTime()方法將消息加入消息隊(duì)列中。最后,sendMessageAtTime()方法會(huì)調(diào)用enqueueMessage()方法將消息插入到消息隊(duì)列中。
接下來(lái),我們來(lái)看一下enqueueMessage()方法的實(shí)現(xiàn):
boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
可以看到,enqueueMessage()方法首先將消息的目標(biāo)對(duì)象設(shè)置為當(dāng)前的Handle對(duì)象,然后如果Handle被標(biāo)記為異步處理,則將消息的異步處理標(biāo)志位設(shè)置為true。最后,enqueueMessage()方法調(diào)用了MessageQueue的enqueueMessage()方法將消息插入到消息隊(duì)列中。
最后,我們來(lái)看一下Handle中另一個(gè)重要的方法,handleMessage()方法:
public void handleMessage(Message msg) {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMesssage(msg);
}
protected void handleMesssage(Message msg) {
}
可以看到,handleMessage()方法首先判斷是否設(shè)置了回調(diào)接口mCallback,如果設(shè)置了,則調(diào)用回調(diào)接口的handleMessage()方法處理消息。如果回調(diào)接口處理了消息,則直接返回,否則調(diào)用Handle自己的handleMesssage()方法處理消息。
總結(jié)一下,安卓中的Handle類是用于實(shí)現(xiàn)線程之間通信的一種機(jī)制,它的實(shí)現(xiàn)依賴于Looper和MessageQueue。當(dāng)一個(gè)線程需要向另一個(gè)線程發(fā)送消息時(shí),它可以創(chuàng)建一個(gè)Handle對(duì)象,并將消息通過Handle對(duì)象發(fā)送到目標(biāo)線程的消息隊(duì)列中。當(dāng)目標(biāo)線程的Looper對(duì)象從消息隊(duì)列中取出消息后,會(huì)將消息交給Handle對(duì)象處理。Handle對(duì)象會(huì)根據(jù)消息的類型和內(nèi)容,調(diào)用自己的handleMessage()方法或回調(diào)接口的handleMessage()方法來(lái)處理消息。