`
cleverGump
  • 浏览: 10447 次
社区版块
存档分类
最新评论

总结一下Handler,Looper,HandlerThread,MessageQueue

阅读更多
转自:http://www.juziku.com/wiki/3880.htm


总结一下Handler,Looper,HandlerThread,MessageQueue

无论是在之前的开发中,还是在最近的面试中,handler跟loop几乎是必接触到的,而最近在面A8音乐时也被问到了handlerthread这个类,现在我就来总结一下三者之间的关系:
   首先来说handlerthread吧,因为他是我最近接触到的,刚在官方文档中看到了它的大概的概述:
  Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.翻译成中文大概是:handlerthread这个类能方便的开启一个包含looper的线程,这个looper也能被用来创建一个handler对象(意思就是把looper以参数形式传递到handler的构造器),并提示我们注意:在用到 handlerthread时,同样必须调用start方法。

Android提供了一个线程类HanderThread类,HanderThread类继承了Thread类,它封装了Looper对象,使我们不用关心Looper的开启和释放的细节问题(因为Looper的构造函数是私有的,对于其实例的获取比较麻烦,而HandlerThread帮我搞定了这些繁琐)。HandlerThread对象中可以通过getLooper方法获取一个Looper对象引用。


其主要的方法有:
 
public Looper getLooper ()
Since: API Level 1
This method returns the Looper associated with this thread. If this thread not been started or for any reason is isAlive() returns false, this method will return null. If this thread has been started, this method will block until the looper has been initialized.

public int getThreadId ()
Since: API Level 1
Returns the identifier of this thread. See Process.myTid().
public boolean quit ()
Since: API Level 5
Ask the currently running looper to quit. If the thread has not been started or has finished (that is if getLooper() returns null), then false is returned. Otherwise the looper is asked to quit and true is returned.
public void run ()
Since: API Level 1
Calls the run() method of the Runnable object the receiver holds. If no Runnable is set, does nothing.

像我之前在项目中使用handler在主线程中对UI进行重绘,其运行机制都是通过发送消息的方式,从子线程中发送消息,然后UI线程中的looper对象接收消息并管理消息队列,默认情况下系统会创建一个无参构造方法的Handler对象,利用这种方法Handler可以自动与当前运行线程(UI线程)的Looper关联,这就是为什么我之前的UI线程中创建Handler时都不需要给其构造器中传递looper对象的原因了。

Public Constructors
public Handler ()
Since: API Level 1
Default constructor associates this handler with the queue for the current thread. If there isn't one, this handler won't be able to receive messages.
public Handler (Handler.Callback callback)
Since: API Level 3
Constructor associates this handler with the queue for the current thread and takes a callback interface in which you can handle messages.
public Handler (Looper looper)
Since: API Level 1
Use the provided queue instead of the default one.
public Handler (Looper looper, Handler.Callback callback)
Since: API Level 3
Use the provided queue instead of the default one and take a callback interface in which to handle messages


通过Handler的这几个构造器就更加知道我之前用法的原因了,完全属于初级阶段,呵呵。
接受消息发送和计划任务的处理是目标线程,它是通过Looper机制维护消息队列,如果应用中有包含更新UI处理,则要把更新UI的处理代码放置在目标线程中,这个时候还要保障更新UI的线程是主线程。

handler发送消息有两种方式,一种是post,另一种是send方式,send方式的话,那么通过handleMessage处理发送过来的消息;Handler对于Message的处理不是并发的。一个Looper 只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的(handleMessage()方法里不应该有耗时操作,可以将耗时操作放在其他线程执行,操作完后发送Message(通过sendMessges方法),然后由handleMessage()更新UI)。

接下来我们再来说说Looper,它是用了收发消息并管理消息队列的,它的构造器是私有的,它的实例化需要通过 loop.prepare()即初始化当前线程为looper,为什么说looper是用来管理消息队列的,因为通过源码发现:
MessageQueue是在Looper的私有构造函数Looper()中实例化的;
总结一下,HandlerThread是被显式地通过new创建的实例,而与它绑定在一起的Looper是在HandlerThread的执行过程中被实例化的,相应的MessageQueue也是在这个过程中实例化的。
  然后之前我也从不少地方,无论是视频还是论坛里得到的结论是:looper.loop实际上就是一个while(true)的死循环,MessageQueue是Looper保留的一份引用,通过它的next()[序列1]获取MessageQueue中的下一个要处理的消息,这个过程中如果没有相应的消息,执行它的线程会用this.wait()释放它所拥有的MessageQueue的对象锁而等待。
分享到:
评论

相关推荐

    了解Android核心:Looper,Handler和HandlerThread

    Handler 在 MessageQueue 中以任务形式排队,Looper 在任务出现时执行它们 MessageQueue. Looper 使线程保持活动状态,循环 MessageQueue 并向相应 Handler 的进程发送消息。 Thread 通过调用 Looper 的 quit() ...

    Thread、Handler和HandlerThread关系详解

    ,这个题目有点意思,对于很多人来说,可能对Thread和Handler很熟悉,主要涉及到Android的消息机制(Handler、Message、Looper、MessageQueue),详见《 从Handler.post(Runnable r)再一次梳理Android的消息机制(以及...

    深入Android Handler,MessageQueue与Looper关系

    关联篇:HandlerThread 使用及其源码完全解析 关联篇:Handler内存泄漏详解及其解决方案 一说到Android的消息机制,自然就会联想到Handler,我们知道Handler是Android消息机制的上层接口,因此我们在开发过程中也只...

    详细分析android的MessageQueue.IdleHandler

    我们知道android是基于Looper消息循环的系统,我们通过Handler向Looper包含的MessageQueue投递Message, 不过我们常见的用法是这样吧? 一般我们比较少接触MessageQueue, 其实它内部的IdleHandler接口有很多有趣的...

    XHandler:XHandler, handler的正确使用姿势与消息传递机制

    XHandler XHandler,handler的正确使用姿势与消息传递机制多线程和任务运行是老话题。 Java本身具有java.util.concurrent包和Fork / Join框架来简化它。... 处理程序使用Looper将任务排队到MessageQueue中,并在任

    android-thread-producer-consumer-example:线程之间的ProducerConsumer模型示例

    因此,没有使用Looper和MessageQueue 。 我们要读取传感器数据的每个线程上都需要一个新的Handler 。 HandlerThread必须将消息发布到这些线程中的每个线程。 现在,我们仅从UI线程读取数据。 想象一下,我们在UI...

    积分管理系统java源码-alibaba-Interview-preparation:阿里巴巴实习生面试个人准备

    积分管理系统java源码 ...Android线程 为什么要同步 Android中使用多线程的方法 裸new一个Thread(失控线程,不推荐) ...Android线程模型就是消息循环,Looper关联MessageQueue,不断尝试从MessageQueue取出Message来

    深入Android HandlerThread 使用及其源码完全解析

    关联篇:深入Android的消息机制源码详解-Handler,MessageQueue与Looper关系 关联篇:Handler内存泄漏及其解决方案 本篇我们将来给大家介绍HandlerThread这个类,以前我们在使用线程执行一个耗时任务时总会new一个...

    Android App在线程中创建handler的方法讲解

    5.Looper:消息循环,从MessageQueue中取出Message进行处理; 6.HandlerThread:继承Thread,实例化时自动创建Looper对象,实现一个消息循环线程. 在Android开发中经常会使用到线程,一想到线程,一般都会想到: new ...

    Android_Studio_Handler:Android Handler 执行绪教学

    Android Handler 执行绪...每一个执行绪都可以有一个讯息伫列(Message Queue)和一个循环器(Looper),在Android中建立的UI执行绪具有讯息伫列和一个循环器,其它worker执行绪预设并没有(可使用HandlerThread产生具有讯息

    android使用多线程更新ui示例分享

    MessageQueue;Looper;HandlerThread。 下面看一段在线程中更新UI的代码: 代码如下:public class MainActivity extends Activity {private TextView timeLable;private Button stopBtn;private Thread mThread;...

    Android开发案例驱动教程 配套代码

    8.4.2 Message和MessageQueue 169 8.4.3 Handler 169 8.4.4 Looper和HandlerThread 172 本章小结 178 第9章 Activity和Intent 179 9.1 Activity 179 9.1.1 创建Activity 179 9.1.2 Activity生命周期 180 9.2...

Global site tag (gtag.js) - Google Analytics