首页 > 代码库 > Android之Handler源代码深入解析

Android之Handler源代码深入解析

闲着没事。就来看看源代码,看看源代码的各种原理,会用仅仅是简单的,知道为什么才是最牛逼的。

Handler源代码分析那,从使用的步骤来边用边分析:

1.创建一个Handler对象:new Handler(getMainLooper(),this);

  这是我经常使用的一个方式。getMainLooper是获取主线程的Looper。this则是实现CallBack的接口

看一下Handler的构造函数

 public Handler() {

        this(nullfalse);

    }

 public Handler(Callback callback) {

        this(callback, false);

    }

public Handler(Looper looper) {

        this(looper, nullfalse);

    }

 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 









Android之Handler源代码深入解析