Handler是如何实现线程之间的切换的

 在Android中,一般情况下(特殊情况先不说)只有UI线程才能对View进行操作,然而为了避免ANR等,耗时操作都放到子线程进行,操作完成之后再切换到UI线程,而Handler正好能够完成从子线程切换到UI线程的工作,那么Handler是如何从子线程切换到UI线程的呢? 

消息传递机制切换


要了解Handler,就首先需要了解Android的消息传递机制,整个消息传递机制有四部分组成:

1.Message 
消息,即线程间传递的对象,传递的信息包含在其中。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。 
2. Message Queue 
消息队列,用来存放通过Handler发布的消息,按照先进先出执行。 
3. Handler 
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。 
4. Looper 
循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。

它们之间的协作如下图,

 

如何实现线程之间切换


最终回到Handler是如何实现线程之间的切换的呢?例如现在有A、B两个线程,在A线程中有创建了handler,然后在B线程中调用handler发送一个message。

通过上面的分析我们可以知道,当在A线程中创建handler的时候,同时创建了MessageQueue与Looper,Looper在A线程中调用loop进入一个无限的for循环从MessageQueue中取消息,当B线程调用handler发送一个message的时候,会通过msg.target.dispatchMessage(msg);将message插入到handler对应的MessageQueue中,Looper发现有message插入到MessageQueue中,便取出message执行相应的逻辑,因为Looper.loop()是在A线程中启动的,所以则回到了A线程,达到了从B线程切换到A线程的目的。

 

总结


1.Handler初始化之前,Looper必须初始化完成。UI线程之所以不用初始化,因为在ActivityThread已经初始化,其他子线程初始化Handler时,必须先调用Looper.prepare()。

2.通过Handler发送消息时,消息会回到Handler初始化的线程,而不一定是主线程。

3.使用ThreadLocal时,需要注意内存泄漏的问题。

通俗点的说法Handler机制其实就是借助共享变量来进行线程切换的.


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值