zoukankan      html  css  js  c++  java
  • Android 消息处理源代码分析(1)

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


    在Android中,通常被使用的消息队列的代码在文件夹sourcesandroid-22androidos下,涉及到下面几个类文件
    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;
        }
       
        
    
    
    
    
    
    
    
    
    
    
    
    


  • 相关阅读:
    autocomplete自动完成搜索提示仿google提示效果
    实现子元素相对于父元素左右居中
    javascript 事件知识集锦
    让 IE9 以下的浏览器支持 Media Queries
    「2013124」Cadence ic5141 installation on CentOS 5.5 x86_64 (limited to personal use)
    「2013420」SciPy, Numerical Python, matplotlib, Enthought Canopy Express
    「2013324」ClipSync, Youdao Note, GNote
    「2013124」XDMCP Configuration for Remote Access to Linux Desktop
    「2013115」Pomodoro, Convert Multiple CD ISO to One DVD ISO HowTo.
    「2013123」CentOS 5.5 x86_64 Installation and Configuration (for Univ. Labs)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5239371.html
Copyright © 2011-2022 走看看