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;
    }
   
    











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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • “idea激活码永久”【2021最新】

    (“idea激活码永久”)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.htmlS32PGH0SQB-eyJsa…

  • PHP正则表达式_python正则匹配字母

    PHP正则表达式_python正则匹配字母一、正则表达式语法(Perl风格)1、模式规则  /php/字符串前后加上两条斜杠即可2、匹配函数  preg_match(‘/php/’,php)  参数1模式  参数2字符串二、正则表达式中的元素介绍  1、正则表达式中包含三种元素分别为:量词、元字符、修饰符  2、前导字符串:就是符号前面的一个字符或字符串量词…

    2022年10月22日
  • blender2.9教程_赖世雄入门篇

    blender2.9教程_赖世雄入门篇Blender2.8基础(一)基础操作与常用快捷键▶Ctrl+N:创建新工程一、视图操作1、放大视图▶视图最大化显示:Ctrl+空格(左键点击视图任意地方可以选择视图,然后按Ctrl+空格可以最大化显示视图。)▶切换全屏模式:Ctrl+Alt+空格2、切换视图▶切换视图:Alt(按住不放)+按住中键上下或左右移动鼠标(每切换一次视图就必须重新按一下中键并移动鼠标)▶……

  • ORA-01017: invalid username/password; logon denied Oracle数据库报错解决方案一

    ORA-01017: invalid username/password; logon denied Oracle数据库报错解决方案一ORA-01017:invalidusername/password;logondenied错误(程序中的用户和密码无法登录,登录被拒)。Oracle11g版本初次安装使用报错:解决方法1创建新用户:打开sqlplus以系统身份登录:指令如下sys/managerassysdba;创建新用户:语法:createuser用户名identifiedb…

  • Hadoop-Shuffle洗牌过程,与combine和partition的关系「建议收藏」

    Hadoop-Shuffle洗牌过程,与combine和partition的关系「建议收藏」Hadoop-Shuffle洗牌过程,与combine和partition的关系

  • ribbon的负载均衡策略_f5负载均衡配置

    ribbon的负载均衡策略_f5负载均衡配置在这里吐槽一句:网上很多文章真是神坑,你不看还好,看了只会问题越来越多,就连之前的问题都没有解决!!!不多说了,Ribbon作为后端负载均衡器,比Nginx更注重的是请求分发而不是承担并发,可以直接感知后台动态变化来指定分发策略。它一共提供了7种负载均衡策略:策略名策略声明策略描述实现说明

    2022年10月13日

发表回复

您的电子邮箱地址不会被公开。

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