Handler(一) Message

100 阅读3分钟

1.Message中的变量

  • int what (定义的消息标志符号,以便接收方可以识别这条消息是来源,每一个Handler有它自己的和消息标志符对应的名称空间,因此不会与其他的Handlers产生冲突。)
  • int arg1,agr2 (如果我们只需要使用少量的整数值,可以使用arg1和arg2代替setData()以减少开销)
  • Object obj (任意的object对象。当使用Messenger跨进程发送消息时,如果obj如果有值,必须实现Parcelable接口。对于其他复杂类型数据的传递,建议使用setData())
  • Messenger replyTo (发送对此消息的回复。如何使用的语义取决于发送者和接收者,实现跨进程通信)
  • int sendingUid (发送方的uid,只针对Messenger发送的消息有效,否则默认UID_NONE=-1)
  • int workSourceUid (记录引起消息进入队列的uid,默认UID_NONE=-1)
  • int FLAG_IN_USE = 1 << 0(用于标记Message对象的状态,判断这条消息是否正在被使用)
  • int FLAG_ASYNCHRONOUS = 1 << 1 (记录当前Message是异步或者同步)
  • int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE (copy出来的FLAG_IN_USE)
  • int flags (标记位)
  • long when (时间戳)
  • Bundle data (用于存储复杂数据)
  • Handler target (处理此条消息的Handler)
  • Runnable callback (要处理任务的callback,是一个Runnable对象,通过Handler.post方法存入Message中,分发后进行回调通知)
  • Message next (链表结构,记录下一个消息)
  • Object sPoolSync (消息池的同步锁,用于消息获取和消息回收)
  • Message sPool (消息池链表的链表头)
  • int sPoolSize (消息池中消息数量,最大为MAX_POOL_SIZE = 50)
  • boolean gCheckRecycle (是否检查消息的recycle()方法,如检查异常则抛出错误)

2.Message的创建

(1) new Message()

  • 直接创建Message对象,可以设置它的属性,但无法复用

(2)Message.obtain()

  • 利用MessagePool实现Message的缓存复用,obtain()方法会判断当前是否有可用的缓存,有的话直接使用sPool并将其从链表中移除后返回,否则就返回一个新的Message()。 1680694801531.png

(3)Message.obtain(Message)

  • Message.obtain()相同,但将orgi所有的值复制到新创建的消息中。 1680695452933(1).png

(4)Message.obtain(Handler)

  • Message.obtain()相同,但将target的值复制到新创建的消息中。
  • Message.obtain(Handler, Runnable),Message.obtain(Handler, int what)等方法也基本一致。 1680695914106.png

3.Message的回收

(1)recycle()

  • 检查回收,如果消息处于使用状态,则不进行回收,否则调用recycleUnchecked()直接回收。 1680696630847.png

(2)recycleUnchecked()

  • 不检查直接回收,会清除消息的所有属性,以完成释放,如果消息池的消息数量没有到达最大值,则进行添加,以完成回收。 1680697213157(1).png

4.消息屏障

  • Android中为了保障一些优先级较高的Message尽快执行,使用的消息屏障机制,即在消息队列中,如果遍历到屏障消息时,就会判断当前队列中是否有异步消息,有的话就会先执行异步消息,后处理同步消息。我们可以通过setAsynchronous()方法,设置消息是否是异步的,这意味着它不受Looper同步屏障的影响。