关于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方法来处理消息。