handler原理解析

Handler是Android的消息处理机制,它与Looper、Message和MessageQueue协同工作。Looper在主线程中以死循环方式检查MessageQueue,当有新消息时进行处理。Message通过享元模式优化性能,存储形式为链表。线程可能因等待Message到达发送时间而阻塞,需要适时唤醒。在子线程直接创建Handler会导致错误,因为Handler依赖于Looper,必须确保线程中有Looper并已启动循环。虽然Looper是死循环,但利用Linux的epoll机制,主线程在无消息时会休眠,不消耗大量CPU资源。
摘要由CSDN通过智能技术生成

handler原理

handler框架是一个安卓的消息处理机制,也可以切换线程传递数据。

handler、looper、message、messageQueue(消息队列)

looper保存在线程中,用Threadlocal保证唯一性。
looper在调用Looper. prepare()初始化的时候,开启一个死循环,轮循是否有新消息要处理。没有消息的时候会调用

message用享元模式,回收后放在复用池中,如果没有已有就新创建,获取对象的方式是调用obtain()。
在把message发送到队列的时候,会绑定一个target就是handler对象,最终在looper所在的线程处理handler的实现方法。

handler在创建时与looper绑定。

Message的存储形式是什么
Message的存储是链表的形式,next相当于链表的尾指针

线程如果阻塞了,需要唤醒线程。为什么会有线程的阻塞呢?
其实MessageQueue内部的消息是按需要发送的时间点从小到大排列的,后面会分析到,从当前if里的when判断也能看出一二,当队首的Message未到达发送的时间点时,说明其当前所有的消息都未到达发送的时间,上面说过,Handler发送消息并不是通过定时器发送的。当队首Message(最近需要发送的Message)未到达发送时间点时,线程被阻塞,所以这里需要根据线程是否阻塞来看是否需要唤醒线程,这样才能使新加入的Message能及时发送出去,不会被阻塞

可以在子线程直接创建一个Handler吗?会出现什么问题,那该怎么做?
不能在子线程直接new一个Handler。因为Handler的工作依赖于Looper,而Looper又是属于某一个线程的,其他线程不能访问,所以在线程中使用Handler时必须要保证当前线程中Looper对象并且启动循环。不然会抛出异常

Looper死循环为什么不会导致应用卡死,会消耗大量资源吗?
对于线程即是一段可执行的代码,当可执行代码执行完成后,线程生命周期便该终止了,线程退出。而对于主线程,我们是绝不希望会被运行一段时间,自己就退出,那么如何保证能一直存活呢?简单做法就是可执行代码是能一直执行下去的,死循环便能保证不会被退出,例如,binder线程也是采用死循环的方法,通过循环方式不同与Binder驱动进行读写操作,当然并非简单地死循环,无消息时会休眠。但这里可能又引发了另一个问题,既然是死循环又如何去处理其他事务呢?通过创建新线程的方式。真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死
-主线程的死循环一直运行是不是特别消耗CPU资源呢? 其实不然,这里就涉及到Linux pipe/epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在Loop的(messagequeue)queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Handler机制是Android中用于实现线程间通信的一种机制。它的主要原理是通过消息队列(MessageQueue)和消息循环(Looper)来实现。 在Android中,每个线程都有一个消息队列,用于存放待处理的消息。当线程需要发送消息时,可以通过Handler消息发送到目标线程的消息队列中。由于每个线程都有自己的消息队列,因此可以实现不同线程之间的通信。 消息队列中的消息会按照先进先出的顺序被处理。当目标线程处于空闲状态时,它会不断地从消息队列中取出消息,并通过Handler的回调方法(Callback)对消息进行处理。处理完一个消息后,它会继续处理下一个消息,直到消息队列为空。 消息循环是实现消息队列轮询的一种机制。它会不断地从消息队列中取出消息,并将消息交给对应的Handler进行处理。当消息队列为空时,消息循环会进入休眠状态,等待新的消息到来。 通过Handler机制,我们可以在不同线程之间发送消息,实现线程之间的通信和任务的调度。它在Android开发中经常被用于更新UI、处理耗时操作等场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Handler原理解析(图文详解)](https://blog.csdn.net/haovin/article/details/89609688)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [AndroidHandler机制实现原理分析](https://download.csdn.net/download/weixin_38719890/15470797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [android Handler机制原理解析(一篇就够,包你形象而深刻)](https://blog.csdn.net/luoyingxing/article/details/86500542)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值