Android 消息处理源代码分析(1)

Android 消息处理源代码分析(1)

Android 消息处理源代码分析(1)

在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件

Handler.java

Looper.java

Message.java

MessageQueue.java

Message.java
public final class Message implements Parcelable {

    public int what;    //消息种类

    public int arg1;    //低开销的整型參数

    public int arg2;

    public Object obj;  //Object型数据

    public Messenger replyTo;  //消息处理完后通知给发送者

    /*package*/ int flags;   //消息标记:正在使用和异步等

    /*package*/ long when;   //消息创建时的时间
    
    /*package*/ Bundle data; //消息附带的额外数据
    
    /*package*/ Handler target; //消息接受者,处理者
    
    /*package*/ Runnable callback; //优先使用回调处理来处理消息
    
    /*package*/ Message next;   //下一个消息。形成链表

    private static Message sPool;    //消息池中的头消息
    

上面中的target,通常由又一次实现的Handler子类的handleMessage函数来处理消息

 public static Message obtain() {     //获取消息的函数,假设有消息的话则获取出来m,链表指针移动一位,否则则返回一条空消息
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }


 public void sendToTarget() {    //发送消息给处理者
        target.sendMessage(this);    //调用Handler.java中的函数
    }

}


MessageQueue.java
public final class MessageQueue {
	
	Message mMessages;    //当前要处理的消息
	
	//当须要从链表中获取一个消息时。就会调用next函数,若消息队列中没有消息,则会堵塞等待,通过调用nativePollOnce函数来完毕
	Message next() {...}
	
	boolean enqueueMessage(Message msg, long when) {     //按时间顺序加入消息
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg + " This message is already in use.");
        }

        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
                msg.recycle();
                return false;
            }

            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
                // Inserted within the middle of the queue.  Usually we don't have to wake
                // up the event queue unless there is a barrier at the head of the queue
                // and the message is the earliest asynchronous message in the queue.
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {      
                nativeWake(mPtr);  //调用底层唤醒函数,管道唤醒
            }
        }
        return true;
    }
   
    











版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109131.html原文链接:https://javaforall.net

(0)
上一篇 2021年9月12日 下午11:00
下一篇 2021年9月12日 下午11:00


相关推荐

  • opencv3编程入门_java基础与入门教程

    opencv3编程入门_java基础与入门教程——韦访 201810111、概述想学习图像处理,不管是机器学习也好,深度学习也好,不会点OpenCV好像有点说不过去吧?所以,现在开始OpenCV的学习。2、读写图片先从图片的读写开始,opencv读取图片的函数是imread,默认情况下,imread函数返回BGR格式的图像,可以用imwrite函数将数据写到本地。下面的代码会将JPG图片转成PNG。import…

    2022年10月3日
    4
  • 常量指针和指针常量的详解一样吗_指针是常量还是变量

    常量指针和指针常量的详解一样吗_指针是常量还是变量说一下常量指针和指针常量的区别。常量指针  指向常量的指针,也就是说指针指向的对象是常量,指向的常量不能修改。指针不是一个常量,可以把指针指向别一个常量。常量指针是我们最常用的,一般声明形式如下:constint*p;intconst*p;例:inta=1,b=2;constint*p;//或者是intconst*p;p=&…

    2022年10月21日
    5
  • idea2021.5.2激活码4月【在线注册码/序列号/破解码】

    idea2021.5.2激活码4月【在线注册码/序列号/破解码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月19日
    49
  • 几种测试技术

    几种测试技术一、单元测试技术1.定义:单元测试又称为模块测试(程序测试),即集中力量来检验软件设计的最小单位——模块。       单元测试(unittesting),是指对软件中的最小可测试单元进行检查和验证。2.目的:单元测试的目的在于发现各模块内部可能存在的各种差错。3.内容/任务:    (1)模块接口测试(单元测试的基础):当模块通过外部设备进行输入/输出…

    2026年1月21日
    4
  • loadrunner压力测试学习笔记

    loadrunner压力测试学习笔记loadrunner学习过程以下仅记录自己的学习过程,有不对之处欢迎指出。压力测试步骤:1.分析需求2.准备脚本3.调试脚本2.准备脚本:可以录制也可以自己写,录制的话先按需求分好每一个action,录制时先切换到当前action,再进行录制。例如:创建一个新的脚本,在action里添加新的action,open_index,submit_login,sign_off(loadrunner自带案例的登录过程)3.调试脚本:(1)回放:脚本准备好后进行回放,需要参数的提前准备好参数,比如注册

    2022年7月18日
    17
  • matlab画三维函数图像代码_excel绘制三维图形

    matlab画三维函数图像代码_excel绘制三维图形例:用plot3函数绘制三维螺旋线。>>t=linspace(0,10*pi,300);>>plot3(20*sin(t),20*cos(t),t,’r’,’linewidth’,2);>>holdon%图形保持>>quiver3(0,0,0,1,0,0,25,’k’,’filled’,’LineWidth’,2);>>quiver3(0,0,0,0,1,0,25,’k’,’fill

    2022年8月31日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号