谈谈Handler机制

    看到文章的标题,就会有人说 handler机制???Rxjava多好用啊,它提供了一个叫io线程的处理,就可以完成线程调度的切换,使用observeOn和subscribeOn可以直接处理网络操作等。对,没错,rxjava是真的好用没有错,但是handler机制也同样重要。在面试中,handler机制被问到的几率还是很大的。当然,网上也有很多比我技术好不知道多少倍的大牛早已经写过不少有关handler机制的文章。本文主要是我自己对handler机制的理解与认识,以加深我对handler机制的理解。
关于handler

    说到handler机制,首先想到的就是Handler、Looper、Message和MessageQueue四个类。Looper:消息队列的处理者/循环者。一个线程可以产生一个Looper对象,由它来管理此线程的消息队列(MessageQueue)。Handler:消息处理者。可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里或者接收Looper从MessageQueue取出所送来的消息。MessageQueue:顾名思义,消息队列,用来存放线程放入的消息,它遵循先进先出原则Message:消息对象。表示要传递的一个消息。内部使用链表数据结构实现一个消息池,用于重复利用,避免大量创建消息对象造成内存浪费。注意:这个不是handler机制的原理。那么handler机制的原理是什么呢?请接着往下看。

handler作用

    在说handler机制原理之前,我们首先得知道handler机制可以干嘛。使用Handler可完成以下两点工作:

            1、消息调度和将来在某个时间点执行一个Runnable。

            2、多个任务加入到一个队列中执行。


在开发中如何使用

    在开发中,官方是不能在子线程中更新ui的,所以我们经常会把需要更新的ui消息发送给handler,通过重写handleMessage()方法进行ui的相关操作。Handler工作流程基本包括Handler、Looper、Message、MessageQueue四部分。但在开发中经常只会使用Handler和Message两个类。Message负责消息的搭载,用target进行消息的标记,obj进行内容的存储。Handler负责消息的分发和处理。

在使用时遇到的问题及注意点

    在使用handler机制的时候,如果将handler设置为私有变量的话,也是很容易造成内存泄漏的。如图:    解决方法有如下两点:

            1、在onDestroy()方法中调用removeCallbacksAndMessages(null)。

            2、设置静态内部类加弱引用。

        对于handler其他的注意点如下:(这个是在一篇文章中看到的)

            1、一个线程Thread只能绑定一个循环器Lopper,但可以有多个处理者Handler

            2、一个循环器Looper可绑定多个处理者Handler

            3、一个处理者Handler只能绑定一个循环器Looper

handler工作流程:

    我理解的Handler的工作流程是按照message->messageQueen->looper->handler的顺序来执行的。一般情况下,在主线程中创建handler,就会直接在主线程中创建Looper、MessageQueue和handler对象。Looper对象的创建一般会通过prepare()方法【好像还有一个prepareMainLooper()的方法】,在创建looper对象的同时也会自动创建一个messagequeue,创建好以后,looper就进入了消息循环,这时候handler就将主线程中的looper和messagequeue进行绑定。在工作线程中handler通过sendmessage()/post()方法发送消息,在send()方法中通过enqueueMessage()这个方法将消息传入messagequeue中。然后looper会同通过next()方法不断的将messagequeue中的message取出,并且通过dispatchmessage()方法将取出的消息分发给handler,handler接收到message后就开始进行消息处理。如果拿不到消息就会一直阻塞线程,直到消息队列中有message。


    总结:

        Android的消息机制也就是handler机制,创建handler的时候会创建一个looper,looper一般为主线程looper,handler通过send发送消息,在send方法中handler会通过enqueueMessage方法向消息队列messagequeue中插入一条消息,同时会把本身的handler通过msg.target=this传入。looper是一个死循环,不断的读取messagequeue中的消息,loop方法会调用messagequeue的next方法来获取新的消息,next操作是一个阻塞操作,当没有消息的时候next方法会一直阻塞,当有消息的时候,looper就会通过dispatch message方法来处理消息。

        handler处理消息的过程:首先,检查message的callback是否为null,不为null就通过handlecallback来处理消息,message的callback是一个runnable对象,实际上是handler的post方法所传递的runnable参数,其次是检查mcallback是否为null,不为null就调用mcallback的handlemessage方法来处理消息。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值