在android開發中,Handler大家會經常看到和用到。這裏不說怎麼使用,主要想一探Handler究竟。首先來看看Handler這個類是如何實現的:
frameworks\base\core\java\android\os中可以查閱到Handler這個類的實現文件。
重點看看他的構造方法的編寫:
public Handler(Callback callback, boolean async) {
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());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
構成方法裏面主要工作是對這幾個變量的初始化:mLooper、mQueue 下面就從這幾個變量開始來解密Handler。
(1)mLooper: 在 Handler中,mLooper可以是通過上面的方法來獲取當前創建該Handler的線程的Looper,也可以在創建時候傳遞一個線程的Looper。那麼Looper是什麼呢?
Looper 是一個線程特有的,用於管理需要在該線程處理的消息Message。Looper.java有原文的翻譯:Class used to run a message loop for a thread.
但是,並不是所有運行中的線程都有自己的Looper,如果一個線程需要自己的Looper,可以通過調用prepare()方法來創建,
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
/// M: ALPS00297986
if (!IS_USER_BUILD) {
long instances = VMDebug.countInstancesOfClass(Looper.class, false);
// check if the looper instance over a limit, it should has some leakage.
if (100 < instances) {
Log.e(TAG, "WARNING: The Looper class instance count has over a limit(100). There should be some leakage of Looper or HandlerThread.");
Log.e(TAG, "Looper class instance count = " + instances);
Log.e(TAG, "Current Thread Name: " + Thread.currentThread().getName());
Thread.currentThread().getThreadGroup().list();
Thread.currentThread().dumpStack();
} //if
}
/// M: ALPS00297986
}
從上面代碼可以看出,一個線程只可以創建一個Looper,
Looper又是如何管理其中的message呢,事實上Looper是使用一個MessageQueue來存儲其中的message的,當我們把message放在MessageQueue後嗎,調用Looper的方法loop()就可以進入一個for (;;)的循環中,不斷的從MessageQueue中取出message,並處理,直到MessageQueue中沒有需要處理的message。
(2)mQueue 看了上面的介紹,就知道mQueue實際就是上面說的Looper的MessageQueue。
所以通過Handler的sendMessage(Message msg)等方法send消息,其實就是把消息放入mQueue中,其實就是對Looper中的MessageQueue的數據處理。
所以使用Handler來處理消息,其實就是這樣一個過程:創建Handler時候,Handler就獲取一個線程的Looper和他的MessageQueue,通過Handler發送處理的消息,其實就是把需要處理的消息放置於一個線程的Looper的MessageQueue中,而後Looper會運行一個for (;;)的死循環來取出消息,並處理。