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


相关推荐

  • 无线网首选dns服务器怎么设置,怎么设置无线路由器dns

    无线网首选dns服务器怎么设置,怎么设置无线路由器dnsDNS在平时上网中扮演重要角色,如果不注意DNS的话,可能会导致网速慢、弹窗广告、网址打不开、打开不是自己想要的网站、劫持等一系列问题,设置好无线路由器的dns尤为重要,下面是学习啦小编整理的设置无线路由器dns的方法,供您参考。设置无线路由器dns的方法首先打开浏览器,然后在网址栏输入192.168.1.1,然后按回车键确认打开,之后就会弹出路由器登录界面。之后输入路由器登录用户名与密码,TP-…

    2022年5月20日
    113
  • 入门黑客必看书籍「建议收藏」

    入门黑客必看书籍「建议收藏」昨天推送的是视频,今天给大家推荐基本入门渗透测试的好书,以结合昨天文章一起学习,忘记了的可以回复“学习之路”会自动跳出文章的,好的话不多说,直接上主菜了!第一本当然是我们网络基础的书,这里推荐《计算机网络自顶向下的方法》,该书从应用层一直往下到物理层层层讲解,很适合刚刚入门信安的学习者学习!第二本就是编程类的书了,因为我学的是python,当然假如你以后想做渗透的话,我估计你用的最后也就是python了,所以这里我只推荐python的书籍了,因为其他的我也不了解,哈哈。这里推荐小甲鱼..

    2022年6月5日
    101
  • AI智能体研究综述

    AI智能体研究综述

    2026年3月16日
    3
  • 文字识别:CRNN「建议收藏」

    文字识别:CRNN「建议收藏」文字识别:CRNN

    2022年4月20日
    100
  • lsof 用法

    lsof 用法

    2021年9月16日
    57
  • 用js实现在Chrome里换行

    用js实现在Chrome里换行buttonid btn onclick get pop up divid a script functionget varbtn document getElementBy btn varp document ge script divid a buttonid btn onclick get

    2025年7月29日
    4

发表回复

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

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