Handler源码阅读

2019-05-17  本文已影响0人  坠叶飘香

1. Handler构造方法

final Looper mLooper;
final MessageQueue mQueue;
public Handler(Callback callback, boolean async) {
  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;
}

2. 给Handler发送一个消息

该Message将会保存在Handler的Looper的MessageQueue的链表结构里
2.1 sendMessage
public final boolean sendMessage(Message msg) {
  return sendMessageDelayed(msg, 0);
}
2.2 sendMessageDelayed
public final boolean sendMessageDelayed(Message msg, long delayMillis){
  if (delayMillis < 0) {
    delayMillis = 0;
  }
  return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
2.3 sendMessageAtTime
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
  MessageQueue queue = mQueue;
  if (queue == null) {
    RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");
    Log.w("Looper", e.getMessage(), e);
    return false;
  }
  return enqueueMessage(queue, msg, uptimeMillis);
}
2.4 enqueueMessage
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
  msg.target = this;  //Message.target设置为Handler
  if (mAsynchronous) {
    msg.setAsynchronous(true);
  }
  return queue.enqueueMessage(msg, uptimeMillis); //调用MessageQueue 的enqueueMessage方法
}
2.5 enqueueMessage
MessageQueue里面安装时间顺序,将msg存放在链表结构里。

frameworks/base/core/java/android/os/MessageQueue.java

boolean enqueueMessage(Message msg, long when) {
  if (msg.target == null) {
    throw new IllegalArgumentException("Message must have a target.");
  }
  if (msg.isInUse()) {
    throw new IllegalStateException(msg + " This message is already in use.");
  }

  synchronized (this) { //同步锁
    if (mQuitting) {
      IllegalStateException e = new IllegalStateException(msg.target + " sending message to a Handler on a dead thread");
      Log.w(TAG, e.getMessage(), e);
      msg.recycle();
      return false;
    }

    msg.markInUse();
    msg.when = when;
    Message p = mMessages;
    boolean needWake;
    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;
     }

    // We can assume mPtr != 0 because mQuitting is false.
    if (needWake) {
      nativeWake(mPtr);
    }
  }
  return true;
}

3 执行链表的消息

3.1 Looper循环处理链表的的Message

frameworks\base\core\java\android\os\Looper.java

public static void loop() {
  final Looper me = myLooper();
  if (me == null) {
    throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
  }
  final MessageQueue queue = me.mQueue;

  // Make sure the identity of this thread is that of the local process,
  // and keep track of what that identity token actually is.
  Binder.clearCallingIdentity();
  final long ident = Binder.clearCallingIdentity();

  for (;;) {
    Message msg = queue.next(); // might block
    if (msg == null) {
      // No message indicates that the message queue is quitting.
      return;
    }
    try {
      msg.target.dispatchMessage(msg);
    } finally {
    }
    msg.recycleUnchecked();
  }
}
3.2 调用Handler的handleMessage方法

android\frameworks\base\core\java\android\os\Handler.java

public void dispatchMessage(Message msg) {
  if (msg.callback != null) {
    handleCallback(msg);
  } else {
    if (mCallback != null) {
      if (mCallback.handleMessage(msg)) {
        return;
      }
    }
    handleMessage(msg); //调用Handler的handleMessage方法
  }
}

4.Message的重用

读取:从Message自身的缓存链表重用Message

frameworks/base/core/java/android/os/Message.java

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处理完后,放入缓存链表
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) { //缓存个数最大值50
      next = sPool;
      sPool = this; //放入表头 
      sPoolSize++;
    }
  }
}
上一篇下一篇

猜你喜欢

热点阅读