一、用法。

Looper为了应付新闻周期,在创建过程中初始化MessageQueue。

Handler在一个消息到当前线程的其他线程

MessageQueue用于存储所述消息

Looper其中线程创建的对象。Handler的handleMessage方法就在哪个线程运行

在创建activity时,android系统本身会为activity创建Looper。

  1. final Handler mainHandler = new Handler(getMainLooper())
  2. {
  3. @Override
  4. public void handleMessage(Message msg)
  5. {
  6. String content = "当前线程:" + "msg:" + msg.what;
  7. Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
  8. }
  9. };
  10. mainHandler.sendEmptyMessage(0x1);

在其他线程中使用handler消息传递时,必须自己创建looper。以下的样例中HandlerThread封装了Looper和MessageQueue,还实现了获取Looper的同步机制,比較好用。

  1. HandlerThread mThread = new HandlerThread("MyThread");
  2. mThread.start();
  3. Handler mHandle = new Handler(mThread.getLooper())
  4. {
  5. @Override
  6. public void handleMessage(Message msg)
  7. {
  8. String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;
  9. System.out.println(content);
  10. }
  11. };
  12. mHandle.sendEmptyMessage(0x2);

二、Looper解析

构造函数:

  1. private Looper(boolean quitAllowed) {
  2. mQueue = new MessageQueue(quitAllowed);
  3. mRun = true;
  4. mThread = Thread.currentThread();
  5. }
  6.  
  7. public static void prepare() {
  8. prepare(true);
  9. }
  10.  
  11. private static void prepare(boolean quitAllowed) {
  12. if (sThreadLocal.get() != null) {
  13. throw new RuntimeException("Only one Looper may be created per thread");
  14. }
  15. sThreadLocal.set(new Looper(quitAllowed));
  16. }

在prepare中创建了Looper实例。并在Looper的构造函数中创建了MessageQueue

  1. public static void loop() {
  2. final Looper me = myLooper();
  3. if (me == null) {
  4. throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
  5. }
  6. final MessageQueue queue = me.mQueue;
  7.  
  8. // Make sure the identity of this thread is that of the local process,
  9. // and keep track of what that identity token actually is.
  10. Binder.clearCallingIdentity();
  11. final long ident = Binder.clearCallingIdentity();
  12.  
  13. for (;;) {
  14. Message msg = queue.next(); // might block
  15. if (msg == null) {
  16. // No message indicates that the message queue is quitting.
  17. return;
  18. }
  19.  
  20. // This must be in a local variable, in case a UI event sets the logger
  21. msg.target.dispatchMessage(msg);
  22.  
  23. // Make sure that during the course of dispatching the
  24. // identity of the thread wasn't corrupted.
  25. final long newIdent = Binder.clearCallingIdentity();
  26.  
  27. msg.recycle();
  28. }
  29. }

在loop()中。Looper不断的通过queue.next()从MessageQueue取消息,然后调用语句msg.target.dispatchMessage(msg) 来运行。这里target为msg消息的发送者Handler,在分析Handler时再来分析。dispatchMessage在普通情况下会调用Handler类的handleMessage来处理消息。也就是上面样例中我们重载的这个handleMessage。

三、Handler解析

Handler的构造函数有非常多,这里选带Looper參数的构造函数

  1. public Handler(Looper looper) {
  2. this(looper, null, false);
  3. }
  4.  
  5. public Handler(Looper looper, Callback callback, boolean async) {
  6. mLooper = looper;
  7. mQueue = looper.mQueue;
  8. mCallback = callback;
  9. mAsynchronous = async;
  10. }

再看sendMessage。

  1. public final boolean sendEmptyMessage(int what)
  2. {
  3. return sendEmptyMessageDelayed(what, 0);
  4. }
  5. public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
  6. Message msg = Message.obtain();
  7. msg.what = what;
  8. return sendMessageDelayed(msg, delayMillis);
  9. }
  10. public final boolean sendMessageDelayed(Message msg, long delayMillis)
  11. {
  12. if (delayMillis < 0) {
  13. delayMillis = 0;
  14. }
  15. return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
  16. }
  17. public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
  18. MessageQueue queue = mQueue;
  19. if (queue == null) {
  20. RuntimeException e = new RuntimeException(
  21. this + " sendMessageAtTime() called with no mQueue");
  22. Log.w("Looper", e.getMessage(), e);
  23. return false;
  24. }
  25. return enqueueMessage(queue, msg, uptimeMillis);
  26. }
  27. private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
  28. msg.target = this;
  29. if (mAsynchronous) {
  30. msg.setAsynchronous(true);
  31. }
  32. return queue.enqueueMessage(msg, uptimeMillis);
  33. }

sendEmptyMessage将message加到了Looper的MessageQueue中,之后Looper在loop()中调用queue.next()

在enqueueMessage里面。我们看到了msg.target = this

  1. public void dispatchMessage(Message msg) {
  2. if (msg.callback != null) {
  3. handleCallback(msg);
  4. } else {
  5. if (mCallback != null) {
  6. if (mCallback.handleMessage(msg)) {
  7. return;
  8. }
  9. }
  10. handleMessage(msg);
  11. }
  12. }

假设没有设置Callback的话,就会执行handleMessage了。

四、HandlerThread解析

HandlerThread继承于Thread,对Looper的操作进行了封装,做了同步处理。

  1. public void run() {
  2. mTid = Process.myTid();
  3. Looper.prepare();
  4. synchronized (this) {
  5. mLooper = Looper.myLooper();
  6. notifyAll();
  7. }
  8. Process.setThreadPriority(mPriority);
  9. onLooperPrepared();
  10. Looper.loop();
  11. mTid = -1;
  12. }
  13.  
  14. public Looper getLooper() {
  15. if (!isAlive()) {
  16. return null;
  17. }
  18.  
  19. // If the thread has been started, wait until the looper has been created.
  20. synchronized (this) {
  21. while (isAlive() && mLooper == null) {
  22. try {
  23. wait();
  24. } catch (InterruptedException e) {
  25. }
  26. }
  27. }
  28. return mLooper;
  29. }

handler looper和messageQueue的更多相关文章

  1. Android消息机制探索(Handler,Looper,Message,MessageQueue)

    概览 Android消息机制是Android操作系统中比较重要的一块.具体使用方法在这里不再阐述,可以参考Android的官方开发文档. 消息机制的主要用途有两方面: 1.线程之间的通信.比如在子线程 ...

  2. Handler Looper源码解析(Android消息传递机制)

    Android的Handler类应该是常用到的,多用于线程间的通信,以及子线程发送消息通知UI线程刷新View等等.这里我主要总结下我对整个消息传递机制,包括Handler,Looper,Messag ...

  3. Android消息处理机制(Handler、Looper、MessageQueue与Message)

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  4. (转)Android消息处理机制(Handler、Looper、MessageQueue与Message)

    转自 http://www.cnblogs.com/angeldevil/p/3340644.html Android消息处理机制(Handler.Looper.MessageQueue与Messag ...

  5. 讲讲Handler+Looper+MessageQueue 关系

    Handler+Looper+MessageQueue这三者的关系其实就是Android的消息机制.这块内容相比开发人员都不陌生,在面试中,或者日常开发中都会碰到,今天就来讲这三者的关系. 概述: H ...

  6. Android的消息机制: Message/MessageQueue/Handler/Looper

    概览   * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...

  7. android学习11——Handler,Looper,MessageQueue工作原理

    Message是Handler接收和处理的消息对象. 每个线程只能拥有一个Looper.它的loop方法读取MessageQueue中的消息,读到消息之后就把消息交给发送该消息的Handler进行处理 ...

  8. Handler,Looper,MessageQueue流程梳理

    目的:handle的出现主要是为了解决线程间通讯. 举个例子,android是不允许在主线程中访问网络,因为这样会阻塞主线程,影响性能,所以访问网络都是放在子线程中执行,对于网络返回的结果则需要显示在 ...

  9. Android 开发 深入理解Handler、Looper、Messagequeue 转载

    转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/73484527 本文已授权微信公众号 fanfan程序媛 独家发布 扫一扫文章底 ...

随机推荐

  1. Linux 系统 杀Oracle 进程

    Linux 系统 杀Oracle 进程 杀掉进程用此方法比较好,能保证杀得干净,而不是用SQL  alter system kill kill -9 `ps -ef|grep "oracle ...

  2. POJ2112 Optimal Milking 【最大流+二分】

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12482   Accepted: 4508 ...

  3. GCD网络多线程---同步运行,异步运行,串行队列,并行队列

    总结:同步(无论是串行还是并行)----不又一次开辟子线程 异步(无论是串行还是并行)----开辟子线程 GCD: dispatch queue 主线程的main queue 并行队列 global ...

  4. 浏览器对象模型(BOM)是什么?(体系结构+知识详解)(图片:结构)

    浏览器对象模型(BOM)是什么?(体系结构+知识详解)(图片:结构) 一.总结 1.BOM操作所有和浏览器相关的东西:网页文档dom,历史记录,浏览器屏幕,浏览器信息,文档的地址url,页面的框架集. ...

  5. 【t062】最厉害的机器人

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] [背景] Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了~ [问题描述] ...

  6. 单个和多个checkbox选中事件怎么写

    单个和多个checkbox选中事件怎么写 一.总结 一句话总结: 1.checkbox的事件方法的话主要是change和click 2.checkbox的属性判断的话主要是prop(判断checked ...

  7. js页面加载函数

    在未加载完文档,使用jquery选择器选择元素后,如果立即绑定事件进行调用,会引起js的报错(can not read property of undefined),导致事件不能绑定成功. alert ...

  8. 怎么样Windows7在配置ASPserverIIS

    在百度经验浏览:http://jingyan.baidu.com/article/5553fa82ed97c765a23934f3.html Internet Information Services ...

  9. 已解决!Fatal error compiling: 无效的标记(maven启动失败)

    问题描述 Fatal error compiling: 无效的标记 maven启动错误..版本号不对 <plugin> <artifactId>maven-compiler-p ...

  10. 【27.40%】【codeforces 599D】Spongebob and Squares

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...