handler


前言

handler是用来发送消息的一种机制


提示:以下是本篇文章正文内容,下面案例可供参考

一、handler是什么?

Handler主要接受子线程发送的数据, 并用此数据配合主线程更新UI.

当应用程序启动时,Android首先会开启一个主线程, 主线程为管理界面中的UI控件,进行事件分发,更新UI只能在主线程中更新,子线程中操作是危险的。这个时候,Handler就需要出来解决这个复杂的问题。由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象(里面包含数据), 把这些消息放入主线程队列中,配合主线程进行更新UI。

二、handler

1.Handler作用

因为在Android中,主线程不建议做耗时的操作,子线程不建议更新UI,但是Android开发,其实就是搭建好页面,将服务器的数据展示到页面上,所以我网络请求使用会非常频繁,而网络请求属于耗时操作,需要放到子线程完成,但一般情况下也不会通过子线程更新UI,需要将请求成功的数据发送到主线程进行UI更新,所以一般会使用到handler。

2.Handler执行流程

首先handler作为任务执行者,一般创建在主线程,当子线程有需要发送的数据,通过创建message对象,使用handler对象将消息发送到messagequeue,messagequeue遵循了队列先进先出的原则,当主线程的looper循环消息的时候,会按照messagequeue队列的顺序循环消息,并将消息给到任务执行者handler去执行任务。

3.Handler执行原理

Handler创建完成后,内部的Looper以及MessageQueue就可以和Handler一起协同工作,然后通过Hadler的post方法将一个Runnable投递到Handler内部的Looper中去处理,也可以通过Handler的send方法发送一个消息,这个消息会在Looper中做处理。Post最终也是通过send来完成的。当Handler的send方法被调用时,他会调用MessageQueue的enqueueMessage方法将这个消息放入消息队列中,然后Looper发现有新消息到来时,就会处理这个消息,最终消息中的Runnable或者Handler的handlerMessage方法就会被调用。Looper试运行在Handler所在的线程,所以就把业务逻辑切换到主线程了

4.Looper的工作原理

Looper在Android的消息机制中扮演着消息循环的角色,就是不停的从MessageQueue中查看是否有新消息,如果有消息就立刻处理,否则就一直阻塞在那里。首先在构造方法中创建一个MessageQueue即队列消息,然后将当前的对象保存起来。Looper除了prepare方法外,还提供了prepareMainLooper方法,这个方法主要是给主线程也就是ActivityThread创建Looper使用的,其本质也是通过prepare方法来实现的。由于主线程的Looper比较特殊,所以Looper提供了一个0getMainLooper方法,通过它可以再任何地方获取到主线程的Looper。Looper也是可以退出的,Looper提供了quit和quitSafely来退出一个Looper,二者的区别是:quit会直接退出Looper,而quieSafely只是假定一个特殊标记,然后把消息队列中的已有消息处理完毕后才安全退出。Looper退出后,通过Handler发送消息失败,这个时候Handler的send方法会返回false。在子线程中,如果手动为其创建Looper,那么在所有的事情完成以后应该调用quit方法来终止消息循环,否则这个子线程就会一直处于等待状态,而如果退出Looper以后,这个线程就会立刻终止,,因此建议不需要的时候终止Looper.loop()方法是个死循环,唯一跳出循环的方式是MessageQueue的next方法返回null。当Looper的quit方法被调用时,Looper就会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,它的next方法就返回null。Looper必须退出,否则loop循环就会无限循环下去。loop方法会调用MessageQueue的next方法,而next方法是一个当没有消息时 是一个阻塞线程,便会导致Looper也会阻塞在那里。当MessageQueue的next方法返回了新的消息,Looper就会处理这条消息:msg.target.disapatchMessage,这里msg.target是发送这条消息的Handler对象,消息交给dispatchMessage方法来处理。而这个dispatchMessage方法是在创建Handler时所用的Looper中执行。这样就把代码逻辑切换到主线程。

5.主线程向子线程发送消息

首先handler肯定是要创建到子线程当中,用于接收主线程发来消息进行处理,但是,因为子线程没有looper对象,首先需要调用looper.prepare(),当主线程发来消息后,已经准备好的looper同样会去消息队列当中循环消息,交给handler,但handler真正能够使用该数据还得调用looper.loop();


总结

因为在Android中,主线程不建议做耗时的操作,子线程不建议更新UI,但是Android开发,其实就是搭建好页面,将服务器的数据展示到页面上,所以我网络请求使用会非常频繁,而网络请求属于耗时操作,需要放到子线程完成,但一般情况下也不会通过子线程更新UI,需要将请求成功的数据发送到主线程进行UI更新,所以一般会使用到handler。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值