Android中Handler原理

來源:互聯網
上載者:User

標籤:回呼函數   訊息佇列   star   進入   eth   block   回調   current   pause   

Handler主要是主線程和子線程通訊。一般子線程中做一些耗時操作做完之後通知主線程來改動UI。

實際上android系統在Activity啟動或者狀態變化等都是通過Handler機制實現的。

首先進入到ActivityThread的main方法中

public static void main(String[] args) {        ……        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }……        Looper.loop();……}

以下主要分析上面幾句代碼。

1.?????Looper.prepareMainLooper();

public static void prepareMainLooper() {        prepare(false);        synchronized (Looper.class) {            if (sMainLooper != null) {                throw new IllegalStateException("The main Looper has already been prepared.");            }            sMainLooper = myLooper();        }}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));//為這個線程會建立一個Looper對象    }

Looper的建構函式例如以下

private Looper(boolean quitAllowed) {        mQueue = new MessageQueue(quitAllowed);//Looper維護了一個訊息佇列        mRun = true;        mThread = Thread.currentThread();}

小結:在調用完Loop.prepare後。就會為當前線程建立一個訊息泵Looper,這個Looper維護了一個訊息佇列MessageQueue

2. sMainThreadHandler =thread.getHandler();?

sMainThreadHandler是Handler對象。getHandler方法例如以下:

final Handler getHandler() {        return mH;    }

看到mH在前面定義為final H mH = new H();實際上H是繼承自Handler。部分代碼例如以下:

private class H extends Handler {        public static final int LAUNCH_ACTIVITY         = 100;        public static final int PAUSE_ACTIVITY          = 101;        ……public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;                ……}……}

小結:這裡相當於平時在UI線程中建立一個Handler實現他的handlerMessage方法。

3.Looper.loop();

public static void loop() {        ……        final MessageQueue queue = me.mQueue;        for (;;) {            Message msg = queue.next(); // might block            if (msg == null) {                return;            }            ……            msg.target.dispatchMessage(msg);……            msg.recycle();        }}

小結:調用Looper.loop()。能夠看到for迴圈。不停地從訊息佇列中取訊息。然後分發msg.target.dispatchMessage(msg); 這裡的msg.target就是Handler對象,指的是處理該Message的Handler。

public void dispatchMessage(Message msg) {        if (msg.callback != null) {            handleCallback(msg);        } else {            if (mCallback != null) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            handleMessage(msg);        }    }

調用dispatchMessage。假設Message設定了回呼函數就運行回調,否則假設定義Handler的時候假設傳進了回呼函數就運行傳進的回調,不然就會運行handlerMessage函數,能夠看到是有優先順序順序的。系統處理的時候因為未設定回調,就會運行handlerMessage。

比方上面的當收到LAUNCH_ACTIVITY訊息,就會運行handleLaunchActivity---- performLaunchActivity---- mInstrumentation.newActivity(cl,component.getClassName(), r.intent); -----mInstrumentation.callActivityOnCreate(activity,r.state); ----- activity.performCreate(icicle);

這樣就運行到了我們平時所謂的Activity的入口onCreate方法。


到如今我們看到了Handler機制在android中的應用。

接下來分析一下handler和Looper是怎麼關聯起來的。

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();//擷取當前線程的Looper if (mLooper == null) { throw new RuntimeException( "Can‘t create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue;//將Looper對象的訊息佇列傳給Handler的成員,使得Handler就能夠操作該訊息迴圈 mCallback = callback; mAsynchronous = async;}

Message類例如以下

public final class Message implements Parcelable {    public int what;    public int arg1;     public int arg2;    ……    Handler target;     //每一個訊息都有一個成員儲存和他關聯的Handler    Runnable callback;   }

接下來我們看一下調用handler的sendMessage送訊息時發生了什麼

public final boolean sendMessage(Message msg)    {        return sendMessageDelayed(msg, 0);    }
最後會運行到:

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {        msg.target = this;//在這裡將this複製給Message的Handler成員。this也就是我們定義的handler對象。        if (mAsynchronous) {            msg.setAsynchronous(true);        }        return queue.enqueueMessage(msg, uptimeMillis);//然後加入到訊息佇列裡面    }

?msg.target = this;所以就有了在loop訊息迴圈函數中的msg.target.dispatchMessage(msg);來分發訊息。因為多台就會運行我們實現的handlerMessage裡面的代碼。

Android中Handler原理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.