Handler、Looper与message消息机制

  1. Handler
    1. 消息机制完整流程
      1. Looper.prepare()//只能执行一次,初始化Loooer,将Looper与当前线程以及MessageQueue绑定,同一个线程只能有一个Looper实例,UI主线程默认执行过了
      2. 创建hanler实例//里面会获取Looper以及与Looper绑定的MessageQueue,handler的async参数控制消息执行是否异步,异步的话不受
        barrier阻塞影响
      3. handler.sendMessage或post//post会创建message作为message的callBack,最终调用MessageQueue的enqueueMessage方法将message添加到MessageQueue中,等待执行
      4. 调用Looper的loop()方法,无限循环从MessageQueue中取消息执行msg.target.dispatchMessage
      5. 最终调用handler的dispatchMessage()方法对消息进行处理,该方法里优先调用msg.callback的handleCallBack方法,最终调用run方法。其次调用mCallBack的handleMessage方法,最后调用handleMessage方法。
      6. 至此一个消息从创建到发送执行完整流程执行完毕
    2. 发送message或Runnable到当前thread的MessageQueue,每一个handler实例与一个Thread以及这个现场唯一的MessageQueue相关联
    3. 初始化函数 public Handler(Callback callback, boolean async),获取Loopoer mLooper = Looper.myLooper(); ,获取MessageQueue
      mQueue mLooper.mQueue;
    4. public boolean sendMessageAtTime(Message msg, long uptimeMillis)---- enqueueMessage(queue, msg, uptimeMillis)//添加消息到消息队列。
    5. public final boolean post(Runnable r)--- m.callback = r--- sendMessageDelayed(getPostMessage(r), 0)
    6. 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 == || when < p.when) {//如果新消息when是0(这里有疑问,默认里面when是0的消息全部执行完了?)或者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 (;;) {//循环遍历queue,按照when排序进行插入
                      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;
      }

    7. void 
      removeMessages(Handler h, int what, Object object) {
          if (h == null) {
              return;
          }

          synchronized (this) {
              Message p = mMessages;

              // Remove all messages at front.
              while (p != null && p.target == h && p.what == what//找到message并删除,删除的message放到回收池里面等待复用
                     && (object == null || p.obj == object)) {
                  Message n = p.next;
                  mMessages = n;
                  p.recycleUnchecked();
                  p = n;
              }

              // Remove all messages after front.
              while (p != null) {//若messageQueue里面之前存在该message全部删除
                  Message n = p.next;
                  if (n != null) {
                      if (n.target == h && n.what == what
                          && (object == null || n.obj == object)) {
                          Message nn = n.next;
                          n.recycleUnchecked();
                          p.next = nn;
                          continue;
                      }
                  }
                  p = n;
              }
          }
      }
  2. Looper
    1. 一个线程只有一个Looper,用来创建MessageQueue,并从中循环分发消息
  3. /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
  4. MessageQueue

    1. //原始的Handler、Looper例子
      class LooperThread extends Thread {
      *      public Handler mHandler;
      *
      *      public void run() {
      *          Looper.prepare();
      *
      *          mHandler = new Handler() {
      *              public void handleMessage(Message msg) {
      *                  // process incoming messages here
      *              }
      *          };
      *
      *          Looper.loop();
      *      }
      *  }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值