zoukankan      html  css  js  c++  java
  • 消息循环相关

      消息循环相关三个大类:Looper,MesseageQueue,Handler

    Looper是发动机,负责轮询MessageQueue,等待Handler发送来的消息,即消息并不是直接加到MessageQueue里,而是通过Handler间接加入

    先看消息循环的基础,Message这个类

    Message实现了Parcelable接口

    一系列的obtain方法构造消息

    copyFrom方法拷贝消息里的某些域

    recycle方法将消息放入消息池,各个域归零

    还有一系列set/get/peek方法查看/设置私有域

    再看三个大类

    Looper(frameworks/base/core/java/android/os/Looper.java):

    Looper提供一些静态函数将Looper类与当前线程绑定,底层依赖的手段的是ThreadLocal

    Looper类要先使用prepare方法准备Looper对象,将其与当前线程绑定,然后使用loop方法开始消息循环,不停的从MessageQueue里抽取消息

    对于UI主线程,则特别准备了prepareMainlLooper方法,存在一个类静态变量sMainLooper保存主线程的Looper(每次切换或者恢复UI线程后会重新赋值)

    主要的API还有以下几个作用:

    get×××,获取内置的私有变量,包括MessageQueue,关联的thread,UI线程的sMainLooper

    myLooper:获取当前的Looper

    quit和quitSafely:退出和安全退出loop循环

    判断当前线程与Looper线程是否一致

     核心函数是loop函数

    这个方法会在头尾利用Binder.clearCallingIdentity方法获取当前进程的PID/UID令牌,并比较是否改变,若改变打log提示

    随后从MessageQueue的next方法里获取消息,用消息的target的dispatchMessage方法分发消息,最后调用消息的recycleUnchecked方法回收消息到消息队列

    Handler(frameworks/base/core/java/android/os/Handler.java):

    Hanlder类可以算是个消息发送/处理中的辅助类,简化过程

    Handler类需要与一个线程绑定,媒介是Looper,要是不传Looper就是创建Handler的那个线程

    这个类提供获取(构造)消息,发送回调代码(Runnable),发送消息,判断消息是否存在,移除消息,获取Messenger对象,分发消息,处理消息,同步处理消息等方法

    由一个接口一个内部类一个静态内部类

    接口Callback用来给外部类实现,这样就不需要继承Handler类也可以处理消息了

    内部类MessengerImpl用来发送带有sendingUID的消息

    静态内部类BlockingRunnable用来实现挂起handler关联的Looper,直到当前消息关联的动作被执行完毕

    主要API如下:

    dispatchMessage方法分发消息,将消息交给设定好的对象来处理,优先级是Message自带的callback域(Runnable对象),内部Callback接口的handleMessage方法,类里的handleMessage方法

    handleMessage方法是空的,要被子类override来重写

    obtainMessage方法用来构造消息

    post,postAtTime,postDelayed,postAtFrontOfQueue方法用来发送Runnable对象

    sendMessage,sendEmptyMessage,sendEmptyMessageDelayed,sendEmptyMessageAtTime,sendMessageAtFrontOfQueue方法用来发送消息

    removeCallbacks,removeMessages方法删除回调

    hasMessage,hasCallbacks方法判断是否由回调

    getLooper获取Looper

    内部类MessengerImpl实现了IMessenger接口,send方法发送该消息,并设置发送者UID

    方法getImessenger返回内部类MessengerImpl

    HandlerThread类方便Handler类与Thread绑定,降低了创建和使用带消息队列的线程的难度(是创建Looper,有了Looper自动创建MessgeQueue),Looper是与线程绑定的,最终还是要在一个相关的线程里创建。HandlerThread类会自动添加同步代码将创建Looper与获取Looper同步,直到创建了一个Looper才会返回这个Looper,不会返回一个空的Looper。在外围先start这个HandlerThread,再获取Looper并将返回的Looper传给相应的Handler类绑定即可

    MessageQueue:

    MessageQueue维护消息队列,与Native world的MessageQueue由紧密联系

    类内部实现了两个Interface,一个静态内部类。

    接口IdleHandler在消息队列没有消息时使用,处理poll状态时的动作

    接口OnFileDescriptorEventListener在相应的文件状态改变(可读,可写,有错误)时被使用

    静态内部类FileDescriptorRecord,记录相应文件状态改变时的监视器OnFileDescriptorEventListener,在被native方法调用的dispatchEvents方法里被调用,执行监视器

    有个重要的判断是needWake

    主要API如下

    enqueueMessage:消息进入队列

    hasMessages:队列中是否有该消息

    removeMessages,removeCallbacksAndMessages,removeAllMessagesLocked,removeAllFutrueMessagesLocked:移除消息

    postSyncBarrier/removeSyncBarrier:添加/移除同步屏障,即target为空的消息,next方法会block在这里

    next:得到下一条消息

    addIdleHandler/removeIdleHandler:添加/删除消息队列为空时的处理类

    isIdle:消息队列是否为空

    isPolling:是否在轮询

    addOnFileDescriptorEventListener/removeOnFileDescriptorEventListener:添加/删除文件状态变化监视器

    域mMessages为当前消息队列的头

    还有个辅助类是Message类,承载消息和参数

    主要代码相关三种case:消息循环,消息分发,消息处理

  • 相关阅读:
    MySQL关键性能监控(QPS/TPS)
    Python小技巧
    Redis高可用演进(一)
    防范XSS攻击
    java引用知识
    ehcache同步原理
    ehcache监控
    SecureCRT使用技巧
    JUC整理笔记五之梳理Varhandle(下)
    JUC整理笔记四之梳理VarHandle(上)
  • 原文地址:https://www.cnblogs.com/cascle/p/5687741.html
Copyright © 2011-2022 走看看