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

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. ZOJ 3430 Detect the Virus(AC自动机 + 模拟)题解

    题意:问你主串有几种模式串.但是所有串都是加密的,先解码.解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0.因为最多可能到255,所 ...

  2. HHVM的全称是"HipHop for PHP",开放源代码。采用PHP许可证授权!

    http://hhvm.com/ https://github.com/xgqfrms/hhvm 什么是HHVM高性能服务器? HHVM是由Facebook公司出品的高性能开源服务器,用来执行hack ...

  3. 二维码 : QRcode

    1 1 1 ★什么是二维码 通俗解释: 二维码是一种能存储信息的特定格式图片. 技术解释: 二维码(2-dimensional bar code) ,又称二维条码, 是用某种特定的几何图形按一定规律在 ...

  4. Web API 设计

    Web API 设计 The Design of Web APIs free online ebook https://www.manning.com/books/the-design-of-web- ...

  5. Node.js & ES Modules & Jest

    Node.js & ES Modules & Jest CJS & ESM CommonJS https://en.wikipedia.org/wiki/CommonJS ht ...

  6. funny 生成器

    funny 生成器 https://www.zhihu.com/question/380741546/answer/1190570384 举牌小人生成器 https://small-upup.upup ...

  7. eui & search select

    eui & search select https://element.eleme.io/#/zh-CN/component/select demo <template> < ...

  8. moment.js & convert timestamps to date string in js

    moment.js & convert timestamps to date string in js https://momentjs.com/ moment().format('YYYY- ...

  9. uniapp 发起网络请求

    推荐下我写的uni-http 创建http-config.js import Vue from 'vue' const BASE_URL = 'http://xxx.com'; if (process ...

  10. 倒计时2天!2021 NGK新加坡区块链峰会与你不见不散!

    1月31日14时,NGK将于新加坡召开"2021 NGK新加坡区块链峰会",并将在全球开启同步直播.   据了解,本次峰会将汇聚全球二十多位顶尖区块链专家学者,与NGK灵石技术团队 ...