Handler的深入瞭解

在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 (;;)的死循環來取出消息,並處理。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章