Android之Handler源代码深入解析

枕上诗书闲处好,门前风景雨来佳。这篇文章主要讲述Android之Handler源代码深入解析相关的知识,希望能为你提供帮助。
闲着没事。就来看看源代码,看看源代码的各种原理,会用仅仅是简单的,知道为什么才是最牛逼的。

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 











【Android之Handler源代码深入解析】


















































    推荐阅读