消息循环相关三个大类: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:消息循环,消息分发,消息处理