重温Handler

Handler机制

  • 是消息机制的暴露出来供使用的上层接口。
  • 整个机制不仅仅是用来更新UI,还可以比如:在IntentService中也用到了handler,但是这里不是用来更新UI,而是用来作为消息队列,向工作线程 HandlerThread 发送任务消息。

工作流程

创建looper(包含mQueue):
  • Looper.prepare()将会new一个Looper对象,Looper构造函数中主要做的是创建 MessageQueue对象mQueue(单链表数结构维护队列结构(FIFO),单链表插入和删除效率高)和获取当前线程对象mThread,实现loopermQueuemThread的绑定,这样就可以保证looper取到的消息(无论来自哪个线程),都会给到当前线程处理
  • Looper.prepare()将looper放入ThreadLocal<Looper> sThreadLocal中备用;sThreadLocal保证了当前线程之后取到的looper一定是当前线程的looper。ThreadLocal类是线程本地变量的容器。
  • 主线程的looper在创建主线程时已经被prepare()了,故不需要再调用Looper.prepare(),因为Android主线程ActivityThread中已经做了对mainLooper的Looper.prepareMainLooper();Looper.loop()操作;
  • 工作线程则必须在线程内调用Looper.prepare()Looper.loop()才能启动整个消息机制,并在线程结束或者不再需要使用消息机制时关闭loopLooper.quit()
创建Handler:
  • 不传入looper参数时:
    • 在哪个线程创建,handler对象中绑定的looper是就是对应的线程的looper对象
  • 传入looper参数时:
    • handler对象中绑定的就是传入的线程的looper,可以传入任意子线程或主线程的looper
  • handler中包含了绑定的轮询获取消息的looper对象以及looper中绑定的用来暂存消息的队列mQueue,这样就保证了消息发送时,是发送到对应线程的mQueue中,并且是这个线程所属的looper负责取用
  • handler中还包含了Callback接口,其中方法handleMessage(Message msg)在接收消息的线程处理消息(重写)
发送消息
  • handler.sendMessage 最终走到 enqueueMessage,其中将每个msg的target赋值为当前handler对象,一以便之后在调用回调Callback
  • 并将msg加入消息队列mQueue:
    • 调用了mQueue.enqueueMessage(Message msg, long when),其中主要做的是锁,以mQueue为对象锁(synchronized(this){...}),确保同一只时间只能有一个消息加入到接收消息的线程的looper的mQueue中
接收消息
  • looper中的loop()方法中,无限循环从mQueue中读取消息,如果mQueue.next()不为空则处理消息
  • 处理消息:不为空的msg中获取target也就是发送了消息的handler,调用它dispatchMessage(msg)方法,其中调用了mCallback.handleMessage(msg),回调消息

在哪一步完成了线程的切换?

  • 消息机制至少存在两个线程(主子 或 子子),在应用中看似一个任务由子线程切换到了主线程(比如),其实只是发了个消息而已。
  • 这个过程中并没有什么神秘的切换线程操作。只是保证msg加入接收者线程的looper的mQueue时的同步(synchronized),消息msg并不是“threadLocal”的数据,而是进程内共享的,那么只要保证线程安全即可:
    • 即上面讲到的:调用了mQueue.enqueueMessage(Message msg, long when),其中主要做的是锁,以mQueue为对象锁(synchronized(this){...}),确保同一只时间只能有一个消息加入到接收消息的线程的looper的mQueue中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值