Android之Handler源碼深入分析,androidhandler

來源:互聯網
上載者:User

Android之Handler源碼深入分析,androidhandler

閑著沒事,就來看看源碼,看看源碼的各種原理,會用只是簡單的,知道為什麼才是最牛逼的。

Handler源碼分析那,從使用的步驟來邊用邊分析:

1.建立一個Handler對象:new Handler(getMainLooper(),this);

  這是我常用的一個方式,getMainLooper是擷取主線程的Looper,this則是實現CallBack的介面

看一下Handler的建構函式

 public Handler() {

        this(null, false);

    }

 public Handler(Callback callback) {

        this(callback, false);

    }

public Handler(Looper looper) {

        this(looper, null, false);

    }

 public Handler(Looper looper, Callback callback) {

        this(looper, callback, false);

 }

 

 @hide

 public Handler(boolean async) {

       this(null, async);

 }

 

    @hide

   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;

    }

 

 

 @hide

 public Handler(Looper looper, Callback callback, boolean async) {

       mLooper = looper;

       mQueue = looper.mQueue;

       mCallback = callback;

       mAsynchronous = async;

 }

 

建構函式的最主要代碼作用是參數的初始化賦值:

 

mLooper = looper;mQueue = looper.mQueue;mCallback = callback;  mAsynchronous = async;

 

這四個參數是主要的參數了。

 

2.建立一個Message。     Message msg = handler.obtainMessage();

直接調用Handler的源碼:

public final Message obtainMessage()

    {

        return Message.obtain(this);

    }

 

Message中得源碼:

 

public static Message obtain(Handler h) {

        Message m = obtain();

        m.target = h;

        return m;

    }

 

 

public static Message obtain() {

        synchronized (sPoolSync) {

            if (sPool != null) {

                Message m = sPool;

                sPool = m.next;

                m.next = null;

                m.flags = 0; // clear in-use flag

                sPoolSize--;

                return m;

            }

        }

        return new Message();

    }

這裡Message是複用的概念,最大能夠保持

private static final int MAX_POOL_SIZE = 50;

50個Message的對象。

sPool變數相當於當前的空的沒有被使用的Message,通過轉換,將當前這個空Message給返回出去。

Message在使用完之後會被回收的,在下面會有提到。

 

3.給Message賦值,並發送Message :    msg.what = 100 ; handler.sendMessage(msg);

 

what是Message中得一個儲值變數。

發送Message則在Handler中得最終指向是以下源碼:

 

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {

        msg.target = this;

        if (mAsynchronous) {

            msg.setAsynchronous(true);

        }

        return queue.enqueueMessage(msg, uptimeMillis);

    }

 oK,sendMessage給發送給了MessageQueue類,看MessageQueue怎麼處理的。

boolean enqueueMessage(Message msg, long when) {

           

    ...........

 

            if (p == null || when == 0 || when < p.when) {

                // New head, wake up the event queue if blocked.

                msg.next = p;

                mMessages = msg;

                needWake = mBlocked;

            } else {

                // Inserted within the middle of the queue.  Usually we don't have to wake

                // up the event queue unless there is a barrier at the head of the queue

                // and the message is the earliest asynchronous message in the queue.

                needWake = mBlocked && p.target == null && msg.isAsynchronous();

                Message prev;

                for (;;) {

                    prev = p;

                    p = p.next;

                    if (p == null || when < p.when) {

                        break;

                    }

                    if (needWake && p.isAsynchronous()) {

                        needWake = false;

                    }

                }

                msg.next = p; // invariant: p == prev.next

                prev.next = msg;

            }

 

            if (needWake) {

                nativeWake(mPtr);

            }

        }

    .......

    }

 

 

截取了中間重要的代碼說一下。這個是用來幹嘛的??

其實就是用來排序的,我們知道的是Message有延遲的訊息,延遲訊息的時間都是不一樣的,when是有大小的,將後執行的Message放到後面。

MessageQueue不是使用一個集合啊或者使用數組去存放的Message,真正排序的是Message的next變數,next變數存放的是當前Message的下一個Message。

發送之後就執行了一個原生的方法nativeWake,這個在這兒就不去探究了。

 

 

4.handler訊息的處理回調Callback.

 

 public static void loop() {

        

 

       ........

 

        for (;;) {

            Message msg = queue.next(); // might block

           

            .....

            msg.target.dispatchMessage(msg);

 

                       .......

 

            msg.recycleUnchecked();

        }

    

        ......

    }

這個那是Looper種的源碼,loop就是迴圈取MessageQueue中得Message的方法。我去掉了代碼,我們可以看到調用了Messa得target變數,這個變數存放的就是Handler,dispatchMessage就是用來分發Message的方法了。看DispatchMessage的源碼:

 

 public void dispatchMessage(Message msg) {

        if (msg.callback != null) {

            handleCallback(msg);

        } else {

            if (mCallback != null) {

                if (mCallback.handleMessage(msg)) {

                    return;

                }

            }

            handleMessage(msg);

        }

    }

 

這個就少了很多了啊!

看到了把,回調了callback。這樣就完成了整個迴圈流程。

 

 

說一下上面的
msg.recycleUnchecked()方法。同樣,看源碼:

 

void recycleUnchecked() {

        // Mark the message as in use while it remains in the recycled object pool.

        // Clear out all other details.

        flags = FLAG_IN_USE;

        what = 0;

        arg1 = 0;

        arg2 = 0;

        obj = null;

        replyTo = null;

        sendingUid = -1;

        when = 0;

        target = null;

        callback = null;

        data = null;

 

        synchronized (sPoolSync) {

            if (sPoolSize < MAX_POOL_SIZE) {

                next = sPool;

                sPool = this;

                sPoolSize++;

            }

        }

    }


從方法名上可以知道這個是用來回收Message的。

在Message使用完畢之後,不是將MEssage對象銷毀,而是存放起來,將其下次重複使用。

 

 

Handler運行大概流程就是這樣的了。

Looper的類的源碼分析,回頭再解析。

 

 

Android開發交流群:417270671  

我的github地址: https://github.com/flyme2012 



 

 

 

 



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.