美文网首页
Android-消息机制

Android-消息机制

作者: 小呀么小黄鸡 | 来源:发表于2021-03-17 11:08 被阅读0次

    整体机制

    一共有四个角色,Handler消息处理者、Looper消息循环、MessageQueue消息队列、Message消息。当handler调用post或者sendMessage时,最后都会调用内部的sendMessageDelayed方法,再通过enqueueMessage方法,设置了msg.target并将消息加入MessageQueue,在MessageQueue中调用了nativeWake唤醒了next方法中的nativePollOnce。而Looper的loop方法此时因为MessageQueue的next方法被阻塞着,直到next方法返回这条msg,Looper的loop调用了msg.target.diapatchMessage。到达了Handler 的事件分发,进行消息处理。

    Thread、Looper、Looper.myLooper,Looper和线程的关系是如何建立关联的,ThreadLocal的实现在其中起了什么作用

    从线程中取出myLooper的过程(字节)
    Looper.java
    有一个static final变量sThreadLocal = new ThreadLocal<Looper>();
    Looper.myLooper()是调用了sThreadLocal.get()
    ThreadLocal.java
    ThreadLocal.get()中获取currentThread,
    拿到Thread中的变量ThreadLocalMap,
    Thread.java
    变量ThreadLocal.ThreadLocalMap,数据被存在了该类中的Entry[] table
    ThreadLocal.java
    map.getEntry(this)->用和HashMap一样的方式计算下标(hashCode&(table.len-1))
    两个变量合流,拿到了ThreadLocalMap.Entry,(Entry是ThreadLocal弱引用和value的键值对组合)
    entry.value就是我们需要的Looper

    Handler中的delay是如何实现的(字节)

    在MessageQueue.next()里,如果头部的这个Message是有延迟而且延迟时间没到的(now < msg.when),会计算一下时间(保存为变量nextPollTimeoutMillis),然后在循环开始的时候判断如果这个Message有延迟,就调用nativePollOnce(ptr, nextPollTimeoutMillis);进行阻塞。nativePollOnce()的作用类似与object.wait(),只不过是使用了Native的方法对这个线程精确时间的唤醒。

    postDelay()一个10秒钟的Runnable A、消息进队,MessageQueue调用nativePollOnce()阻塞,Looper阻塞;
    紧接着post()一个Runnable B、消息进队,判断现在A时间还没到、正在阻塞,把B插入消息队列的头部(A的前面),然后调用nativeWake()方法唤醒线程;
    MessageQueue.next()方法被唤醒后,重新开始读取消息链表,第一个消息B无延时,直接返回给Looper;
    Looper处理完这个消息再次调用next()方法,MessageQueue继续读取消息链表,第二个消息A还没到时间,计算一下剩余时间(假如还剩9秒)继续调用nativePollOnce()阻塞;
    直到阻塞时间到或者下一次有Message进队;
    这样,基本上就能保证Handler.postDelayed()发布的消息能在相对精确的时间被传递给Looper进行处理而又不会阻塞队列了。

    Handler如果没有消息处理是阻塞的还是非阻塞的(字节)

    https://blog.csdn.net/u010126792/article/details/85091348
    阻塞的。Looper.loop阻塞在MessageQueue的next方法中,有一个nativePollOnce的native方法,而在MessageQueue的enqueueMessage方法的最后nativeWake方法可以唤醒阻塞,使用了epoll机制

    在next()方法内部,如果有阻塞(没有消息了或者只有Delay的消息),会把mBlocked这个变量标记为true,在下一个Message进队时会判断这个message的位置,如果在队首并且时间满足条件,会调用nativeWake()方法唤醒线程!

    Handler的post和postDelay的区别(字节)

    都是用sendMessageDelayed实现,postDelay设置了delay数值,而post的delay数值为0,接着调用sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)

    一个线程可以有几个Looper可以对应几个Handler,同一线程,HandlerA能向HandlerB发送消息吗(字节)

    一个线程只能又一个Looper,可以有多个Handler,不能互相发送消息,因为dispatchMessage中通过msg.target记录了发送这个Message的Handler

    Looper如何在子线程中创建(字节)

    直接使用HandlerThread
    Looper.prepare();//Looper初始化
    mHandler = new Handler(Looper.myLooper());
    Looper.loop();//死循环

    线程中的Looper创建

    在主线程ActivityThread创建时进行了主线程Looper的初始化,handler依赖于Looper,通过构造函数建立联系,而MessageQueue的实例在Looper中,新建的线程需要我们自己调用Looper.prepare();通过构造函数传入handler,然后用Looper.loop();开启消息机制。Android规定访问UI只能在主线程中进行,否则抛出异常(UI控件不是线程安全的,加锁使逻辑复杂,访问效率降低),通过ViewRootImpl对UI操作做了验证,由checkThread方法完成。

    handler.post(Runnable) runnable是如何执行的,handler分发的顺序如何

    自己新建了Message并且把Runnable赋值给了Message的callback,在loop中会调用msg.target.dispatchMsg()以一定顺序执行第一顺序就是Message中的callback

    1. Message中的callback
    2. 构造函数中传入的callback
    3. 由其子类重写的handleMessage
      handler的Callback和handlemessage都存在,但callback返回true handleMessage还会执行么
      不执行,mCallback.handleMessage如果返回true,会return,即使handleMessage被重写了,也轮不到执行了

    IdleHandler

    https://blog.csdn.net/jdsjlzx/article/details/110532500
    Q:IdleHandler 有什么用?
    IdleHandler 是 Handler 提供的一种在消息队列空闲时,执行任务的时机;
    当 MessageQueue 当前没有立即需要处理的消息时,会执行 IdleHandler;
    Q:MessageQueue 提供了 add/remove IdleHandler 的方法,是否需要成对使用?
    不是必须;
    IdleHandler.queueIdle() 的返回值,可以移除加入 MessageQueue 的 IdleHandler;
    Q:当 mIdleHanders 一直不为空时,为什么不会进入死循环?
    只有在 pendingIdleHandlerCount 为 -1 时,才会尝试执行 mIdleHander;
    pendingIdlehanderCount 在 next() 中初始时为 -1,执行一遍后被置为 0,所以不会重复执行;
    Q:是否可以将一些不重要的启动服务,搬移到 IdleHandler 中去处理?
    不建议;
    IdleHandler 的处理时机不可控,如果 MessageQueue 一直有待处理的消息,那么 IdleHander 的执行时机会很靠后;
    Q:IdleHandler 的 queueIdle() 运行在那个线程?
    陷进问题,queueIdle() 运行的线程,只和当前 MessageQueue 的 Looper 所在的线程有关;
    子线程一样可以构造 Looper,并添加 IdleHandler;

    相关文章

      网友评论

          本文标题:Android-消息机制

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