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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jvm系列(七):jvm调优-工具篇「建议收藏」

    jvm系列(七):jvm调优-工具篇「建议收藏」16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化。工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相关问题,长长可以到达事半功倍的效果来。jvm监控分析工具一般分为两

    2022年5月20日
    39
  • pycharm设置项目编码「建议收藏」

    pycharm设置项目编码「建议收藏」pycharm设置项目编码1.pycharm-file-setting2.Editor-FileEncodings3.选择自己想要的编码4.点击确定

    2022年8月26日
    8
  • 用Python读取CSV文件的5种方式

    用Python读取CSV文件的5种方式典型的数据集stocks.csv:一个股票的数据集,其实就是常见的表格数据。有股票代码,价格,日期,时间,价格变动和成交量。这个数据集其实就是一个表格数据,有自己的头部和身体。第一招:简单的读取我们先来看一种简单读取方法,先用csv.reader()函数读取文件的句柄f生成一个csv的句柄,其实就是一个迭代器,我们看一下这个reader的源码:喂给reader一个可迭代对象或者是文件的object,然后返回一个可迭代对象。首先读取csv文件,然后用csv.reader生成一个csv迭代器

    2022年7月21日
    13
  • 胶南人才交流中心[通俗易懂]

    胶南人才交流中心[通俗易懂]电话:0532-86164282山东胶南珠海中路273号邮编:266400

    2022年7月3日
    33
  • c中getline的用法_enum用法

    c中getline的用法_enum用法getline()用法getline是C++标准库函数;它有两种形式,一种是头文件<istream>中输入流成员函数;一种在头文件<string>中普通函数;它遇到以下情况发生会导致生成的本字符串结束:(1)到文件结束,(2)遇到函数的定界符,(3)输入达到最大限度。输入流成员函数getline()函数语法结构:在<istream>中的g…

    2025年7月20日
    4
  • android AudioTrack 播放 正弦波 方波「建议收藏」

    MainActivity.java: 1.主类,播放方波(提供byteDate)和正弦波。 2.提供三个按钮分别为短方波(btnPlayFS)、长方波(btnPlayFL)、正弦波(btnPlayZ),其功能如下: 2.1.btnPlayFS/btnPlayFL单击事件:实例化WaveOutF(方波类),调用sendByteDate(byte[],length)方

    2022年4月12日
    48

发表回复

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

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