17 Handler-Java层

作者: 凤邪摩羯 | 来源:发表于2020-10-20 17:00 被阅读0次

1 使用方式

https://www.jianshu.com/p/e172a2d58905

2 工作原理

image.png
image.png
https://www.jianshu.com/p/f0b23ee5a922

3 源码分析

image.png

https://www.jianshu.com/p/b4d745c7ff7a

4 享元模式

https://www.jianshu.com/p/ce6748cfe0d2

https://www.jianshu.com/p/e252ddd16097

5 Handler延时执行原理

Handler的postDelay是通过设置Message的when为delay的时间,我们知道当我们的应用开启的时候,会同步开启Looper.loop()方法循环的,不停的通过MeassgeQueue的next方法:

Message next() {
  ......
  int nextPollTimeoutMillis = 0;
  for (;;) {
   if (nextPollTimeoutMillis != 0) {
    Binder.flushPendingCommands();
   }
   nativePollOnce(ptr, nextPollTimeoutMillis);
   synchronized (this) {
    // Try to retrieve the next message. Return if found.
    final long now = SystemClock.uptimeMillis();
    Message prevMsg = null;
    Message msg = mMessages;
    if (msg != null && msg.target == null) {
     // Stalled by a barrier. Find the next asynchronous message in the queue.
     do {
      prevMsg = msg;
      msg = msg.next;
     } while (msg != null && !msg.isAsynchronous());
    }
    if (msg != null) {
     if (now < msg.when) {
      // Next message is not ready. Set a timeout to wake up when it is ready.
      nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
     } else {
      // Got a message.
      mBlocked = false;
      if (prevMsg != null) {
       prevMsg.next = msg.next;
      } else {
       mMessages = msg.next;
      }
      msg.next = null;
      if (DEBUG) Log.v(TAG, "Returning message: " + msg);
      msg.markInUse();
      return msg;
     }
    } else {
     // No more messages.
     nextPollTimeoutMillis = -1;
    }
  ......
  }
 }

当我们向MessageQueue插入一条延迟的Message的时候,Looper在执行loop方法,底层会调用epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);其中的timeoutMillis参数指定了在没有事件发生的时候epoll_wait调用阻塞的毫秒数(milliseconds)。这样我们在之前的时间内这个时候阻塞了是会释放cpu的资源,等到延迟的时间到了时候,再监控到事件发生。在这里可能有人会有疑问,一直阻塞,那我接下来的消息应该怎么执行呢?

我们可以看到当我们插入消息的时候的方法:

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) {
    msg.next = p;
    mMessages = msg;
    needWake = mBlocked;
   } else {
    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;
   }
   mQuitting is false.
   if (needWake) {
    nativeWake(mPtr);
   }
  }
  return true;
 }

阻塞了有两种方式唤醒,一种是超时了,一种是被主动唤醒了,在上面我们可以看到当有消息进入的时候,我们会唤醒继续执行,所以我们的即时消息在延迟消息之后插入是没有关系的。然后在延迟时间到了的时候,我们也会被唤醒,执行对应的消息send,以达到延迟时间执行某个任务的目的。
优势:这种延迟在阻塞的时候,是会释放cpu的锁,不会过多地占用cpu的资源。

6 补充

image.png
image.png
image.png
image.png

7 常见问题

https://www.jianshu.com/p/af52dd10058c

相关文章

  • 17 Handler-Java层

    1 使用方式 https://www.jianshu.com/p/e172a2d58905[https://www...

  • 锻炼倾听能力

    2021-08-17 非暴力沟通觉察日记 第 一期 第 1 层 8日 17累9层 ☞『阅享日记』邱红梅 【每个...

  • 17层的约会

    谢小天最近发现自己总是不经意的会想起孟城。她突然一惊,难道自己爱上他了。这不可能,谢小天是有夫之妇,而孟城是有妇之...

  • openstack学习笔记2

    2019-11-17 1.SDN 灵活调配网络资源 应用层 控制层 基础设施层,其中控制层是很核心的一层 2.Op...

  • 17岁生命的叹息

    昨天听到、看到17岁男孩跳桥轻生的过程。心里的悲哀、是一层层升起的。 17岁的少年,与我儿子相仿的年纪。他从小会遇...

  • [幻想]蔓层生(17)

    蔓层生目录 连载碎语:在生活的细节里,那些不经意的时光并没有波澜壮阔,却在最后连绵成了百里荷田,缓缓地在生命中散发...

  • 17 Handler-Native层

    本文基于Android 6.0的源代码,来分析native层的消息处理机制 相关源码 一、概述[http://gi...

  • 下楼梯17层

    今早起来小腿肌肉酸痛,估计是昨天脑袋一发热的不知道哪根筋不对,按来电梯,又跑去走楼梯下去,17楼走下去,...

  • 南通启东-恒大世纪海岸!欢迎您!

    南通启东-恒大世纪海岸 【恒大世纪海岸】 价格:9000元/平 洋房:(8层)16——144 高层:(17层)52...

  • 放在17层楼梯间的猫粮少了

    昨晚在17层的楼梯间放了猫粮和猫窝,想着如果猫粮不见少,就转移到16层,如果再不见少,就到15层,每天下移一层……...

网友评论

    本文标题:17 Handler-Java层

    本文链接:https://www.haomeiwen.com/subject/pgkjyktx.html