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

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. Tensorflow2的基本用法

    张量表示数据,用计算图搭建神经网络,用会话执行计算图,优化线上的权重(参数)->得到模型. 张量(tensor):多维数组(列表)                 阶:张量的维数. 数据类型: ...

  2. ZOJ 3494 BCD Code(AC自动机 + 数位DP)题解

    题意:每位十进制数都能转化为4位二进制数,比如9是1001,127是 000100100111,现在问你,在L到R(R <= $10^{200}$)范围内,有多少数字的二进制表达式不包含模式串. ...

  3. 微服务架构Day05-SpringBoot之Servlet

    旧版 配置嵌入式Servlet容器 SpringBoot默认使用Tomcat作为嵌入式Servlet容器 如何定制和修改Servlet容器相关配置 1.在配置文件中定制和修改Servlet容器有关的配 ...

  4. js uppercase first letter

    js uppercase first letter const str = `abc`; str.slice(0, 1).toUpperCase(); // "A" str.sli ...

  5. JavaScript this All In One

    JavaScript this All In One js, this, bind, call, apply, new, function, arrow function, constructor f ...

  6. React Hooks vs React Class vs React Function All In One

    React Hooks vs React Class vs React Function All In One React Component Types React Hooks Component ...

  7. DRM & 音视频 & 防盗链

    DRM & 音视频 & 防盗链 DRM Digital Rights Management / 数字版权管理 https://en.wikipedia.org/wiki/Digital ...

  8. Scratch 游戏开发

    Scratch 游戏开发 可视化少儿编程 https://scratch.mit.edu/ Scratch Desktop https://scratch.mit.edu/download https ...

  9. You Don't Know Chrome Features

    You Don't Know Chrome Features URL auto convert to QR Code click the tab URL address click QRCode ic ...

  10. .pyc & Python

    .pyc & Python Python bytecode / 字节码 Python compiles the .py files and saves it as .pyc files , s ...