基于消息队列的线程通信:
          消息队列与线程循环
          

MessageQueue:     
     利用链表来管理消息。
     
          

Message:


     通常由Handler的子类的handleMessage()函数来处理该消息。


由android.os.Handler类来处理消息Message:
     
Handler:
     由Handler来处理消息,由其函数dispatchMessage()完成。
    public void dispatchMessage(Message msg) {

if (msg.callback != null) {

            handleCallback(msg);

        } else {

            if (mCallback != null) {

                if (mCallback.handleMessage(msg)) {

                    return;

                }

            }

            handleMessage(msg); //若消息没有指定处理消息的对象,则由Handler的子类来完成。其子类必须实现handleMessage()方法。

        }

    }




Looper:

     Looper与线程关联,一个线程最多有一个Looper。Looper实例保存到宿主线程的线程局部存储中。

     指定了Looper就意味着指定了在哪个线程中处理;为消息指定的Handler则决定如何处理消息。
     
     Looper中拥有一个消息队列MessageQueue,该消息队列由Looper创建,属于它所有。

    private Looper(boolean quitAllowed) {

        mQueue = new MessageQueue(quitAllowed);//创建Looper要处理的消息队列,是否运行线程退出,由消息队列决定。

        mRun = true;

        mThread = Thread.currentThread();//得到当前线程

    }

    public static void loop() {

        final Looper me = myLooper();

        if (me == null) {

            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");

        }

        final MessageQueue queue = me.mQueue;



        // Make sure the identity of this thread is that of the local process,

        // and keep track of what that identity token actually is.

        Binder.clearCallingIdentity();

        final long ident = Binder.clearCallingIdentity();



        for (;;) {

            Message msg = queue.next(); // might block//取得一个消息

            if (msg == null) {//消息体为空则表示退出

                // No message indicates that the message queue is quitting.

                return;

            }



            // This must be in a local variable, in case a UI event sets the logger

            Printer logging = me.mLogging;

            if (logging != null) {

                logging.println(">>>>> Dispatching to " + msg.target + " " +

                        msg.callback + ": " + msg.what);

            }



            msg.target.dispatchMessage(msg);//调用消息指定的接收者Handler来处理它



            if (logging != null) {

                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);

            }



            final long newIdent = Binder.clearCallingIdentity();

            if (ident != newIdent) {

                Log.wtf(TAG, "Thread identity changed from 0x"

                        + Long.toHexString(ident) + " to 0x"

                        + Long.toHexString(newIdent) + " while dispatching to "

                        + msg.target.getClass().getName() + " "

                        + msg.callback + " what=" + msg.what);

            }



            msg.recycle();//丢弃消息,循环再利用

        }

    }


Handler:消息的处理者。一旦为消息指定了某个特定的处理者Handler,也就确定了在哪个线程的上下文中去处理以及如何处理消息。

          实际上是根据Handler的变量mLooper所代表的Looper所在的线程,来决定该Handler运行在哪个线程中。

         在一个线程中创建的Handler并不一定运行在该线程中,需要判断该Handler的Looper变量在哪个线程中。

       public Handler() {

if (FIND_POTENTIAL_LEAKS) {

            final Class<? extends Handler> klass = getClass();

            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&

                    (klass.getModifiers() & Modifier.STATIC) == 0) {

                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());

            }

        }



        mLooper = Looper.myLooper();//通过线程局部存储,获得本线程的Looper:当程序没有另启一个线程时,该Looper就是主线程的Looper。

          

        if (mLooper == null) {

            throw new RuntimeException(

                "Can't create handler inside thread that has not called Looper.prepare()");

        }

        mQueue = mLooper.mQueue;

        mCallback = null;

    }



         public void dispatchMessage(Message msg) {

if (msg.callback != null) {

            handleCallback(msg);//消息所指定的CallBack,实际就是Runnable

        } else {

            if (mCallback != null) {

                if (mCallback.handleMessage(msg)) {

                    return;

                }

            }

            handleMessage(msg);//Handler的方法

        }

    }

android消息线程和消息队列的更多相关文章

  1. android 进程/线程管理(一)----消息机制的框架

    一:android 进程和线程 进程是程序运行的一个实例.android通过4大主件,弱化了进程的概念,尤其是在app层面,基本不需要关系进程间的通信等问题. 但是程序的本质没有变,尤其是多任务系统, ...

  2. android 进程/线程管理(四)续----消息机制的思考(自定义消息机制)

    继续分析handler 和looper 先看看handler的 public void dispatchMessage(Message msg) { if (msg.callback != null) ...

  3. android 进程/线程管理(四)----消息机制的思考(自定义消息机制)

    关于android消息机制 已经写了3篇文章了,想要结束这个系列,总觉得少了点什么? 于是我就在想,android为什么要这个设计消息机制,使用消息机制是现在操作系统基本都会有的特点. 可是andro ...

  4. Android源码分析-消息队列和Looper

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17361775 前言 上周对Android中的事件派发机制进行了分析,这次博主 ...

  5. android handle详解2 主线程给子线程发送消息

    按照android handler详解分析的原理我们可以知道,在主线程中创建handle对象的时候,主线程默认创建了一个loop对象使用threalocal函数将loop对象和主线程绑定. 我们能不能 ...

  6. 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)

    1.创建和终止线程 在MFC程序中创建一个线程,宜调用AfxBeginThread函数.该函数因参数不同而具有两种重载版本,分别对应工作者线程和用户接口(UI)线程. 工作者线程 CWinThread ...

  7. Android:子线程向UI主线程发送消息

    在Android里,UI线程是不同意被堵塞的.因此我们要将耗时的工作放到子线程中去处理. 那么子线程耗时处理后要如何通知UI线程呢? 我们能够在UI主线程中创建一个handler对象,然后通过重写其h ...

  8. python 实现多个线程间消息队列传递,一个简单的列子

    #-*-coding:utf8-*-"""Producer and consumer models: 1. There are many producers and co ...

  9. Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息

    之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...

随机推荐

  1. Leetcode(104)-二叉树的最大深度

    给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,null,15,7], ...

  2. 银河麒麟V10安装ASP.NET Core并配置Supervisor让网站开机自动运行

    银河麒麟高级服务器操作系统V10是针对企业级关键业务,适应虚拟化.云计算.大数据.工业互联网时代对主机系统可靠性.安全性.性能.扩展性和实时性的需求,依据CMMI 5级标准研制的提供内生安全.云原生支 ...

  3. SpringBoot进阶教程(七十)SkyWalking

    流行的APM(Application Performance Management工具有很多,比如Cat.Zipkin.Pinpoint.SkyWalking.优秀的监控工具还有很多,其它比如还有za ...

  4. vue & this.$route & this.$router

    vue & this.\(route & this.\)router const User = { template: '<div>User</div>' } ...

  5. SCSS variable for loop All In One

    SCSS variable for loop All In One @each $r: red; $g: green; $b: blue; $colors: ( 1: $r, 2: $g, 3: $b ...

  6. Winter Bash & Stack Overflow

    Winter Bash & Stack Overflow https://stackoverflow.com/users/5934465/xgqfrms#winter-bash https:/ ...

  7. i18n 和 L10n (internationalization and localization) 国际化与本地化(具有全球战略眼光的公司企业的必由之路)

    i18n 和 L10n (internationalization and localization)  国际化与本地化(具有全球战略眼光的公司企业的必由之路) 1 1 https://zh.wiki ...

  8. 使用 js 实现一个简易版的 async 库

    使用 js 实现一个简易版的 async 库 具有挑战性的前端面试题 series & parallel 串行,并行 refs https://www.infoq.cn/article/0NU ...

  9. macOS warning emoji render bug

    macOS warning emoji render bug ️ macOS render bug Apple Color Emoji fonts install old version fonts ...

  10. uniapp vue mixin使用

    这个mixin的翻版,主要用来分离处理列表数据逻辑 我用了覆写模式 创建mixin ListMoreDataMixin // 由于没有超类的限制这里要判断下 function ____checkGet ...