Handler Looper Message

首先看Looper,点击在线查看Android源码地址,
public final class Looper {
    private static final String TAG = "Looper";
     // sThreadLocal.get() will return null unless you've called prepare().
     static final ThreadLocal sThreadLocal = new ThreadLocal();
     private static Looper sMainLooper;  // guarded by Looper.class
 
     final MessageQueue mQueue;
     final Thread mThread;
 
    private Printer mLogging;
这个Looper是一个final类,不能被继承,可以看到有一个ThreadLocal存储Looper,看他的注释
 // sThreadLocal.get() will return null unless you've called prepare().意思是你取sThreadLocal 的值得时候,必须先调用prepare,还有一个Thread对象和MessageQueue对象
public static void More ...prepare() {
71         prepare(true);
72     }
73 
74     private static void prepare(boolean quitAllowed) {
75         if (sThreadLocal.get() != null) {
76             throw new RuntimeException("Only one Looper may be created per thread");
77         }
78         sThreadLocal.set(new Looper(quitAllowed));
79     }
看prepare()方法,调用prepare(true);75行如果sThreadLocal.get()即Looper不为空,就会抛出一个异常,所以就保证了只有一个Looper,再看78行,new Looper(quitAllowed);创建可唯一一个Looper对象,
进入new Looper(quitAllowed);这个构造方法。
186    private Looper(boolean quitAllowed) {
187        mQueue = new MessageQueue(quitAllowed);
188        mThread = Thread.currentThread();
189    }
可以看到在这个私有的构造方法中,实例化了唯一一个MessageQueue对象,证明了一个Looper存在了一个MessageQueue,之间是一对一。
既然Looper已经创建出来了,就该loop循环取消息了。进入loop方法
109    public static void loop() {
110        final Looper me = myLooper();
111        if (me == null) {
112            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
113        }
114        final MessageQueue queue = me.mQueue;
115
116        // Make sure the identity of this thread is that of the local process,
117        // and keep track of what that identity token actually is.
118        Binder.clearCallingIdentity();
119        final long ident = Binder.clearCallingIdentity();
120
121        for (;;) {
122            Message msg = queue.next(); // might block
123            if (msg == null) {
124                // No message indicates that the message queue is quitting.
125                return;
126            }
127
128            // This must be in a local variable, in case a UI event sets the logger
129            Printer logging = me.mLogging;
130            if (logging != null) {
131                logging.println(">>>>> Dispatching to " + msg.target + " " +
132                        msg.callback + ": " + msg.what);
133            }
134
135            msg.target.dispatchMessage(msg);
136
137            if (logging != null) {
138                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
139            }
140
141            // Make sure that during the course of dispatching the
142            // identity of the thread wasn't corrupted.
143            final long newIdent = Binder.clearCallingIdentity();
144            if (ident != newIdent) {
145                Log.wtf(TAG, "Thread identity changed from 0x"
146                        + Long.toHexString(ident) + " to 0x"
147                        + Long.toHexString(newIdent) + " while dispatching to "
148                        + msg.target.getClass().getName() + " "
149                        + msg.callback + " what=" + msg.what);
150            }
151
152            msg.recycleUnchecked();
153        }
154    }

    
Return the Looper object associated with the current thread. Returns null if the calling thread is not associated with a Looper.
159
160    public static Looper myLooper() {
161        return sThreadLocal.get();
162    }
110行调用了myLooper()方法,而此方法返回的是唯一一个Looper实例,如果实例为空 ,先调用一下prepare()方法,产生一个Looper唯一实例就行了。然后114行,从Looper实例
 
  
中取出MesageQueue实例,121行进入for循环,122行queue.next()返回一个消息对象,这个方法是一个阻塞方法,比如生产机器如果没有东西可以制造就wait使阻塞,有了就notify。然后看135行,
msg.target.dispatchMessage(msg),msg的target从何而来,我们来看看Handler就知道了。一般我们都是写
private Handler myHandler = new Handler()
    {
        public void handleMessage(android.os.Message msg)
        {
            switch (msg.what)
            {
            case XX:
                //可以执行UI操作
                Log.i(TAG,(String)msg.obj);
                break;
            }
        }
    };
我们可以看到new Handler()并且实现了一个匿名内部类,接口中的方法是handleMessage(android.os.Message msg)我们先看new Hnalder
113    public More ...Handler() {
114        this(null, false);
115    }
调用了另外一个构造函数
this(null,false)
187
188    public More Handler(Callback callback, boolean async) {
189        if (FIND_POTENTIAL_LEAKS) {
190            final Class klass = getClass();
191            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
192                    (klass.getModifiers() & Modifier.STATIC) == 0) {
193                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
194                    klass.getCanonicalName());
195            }
196        }
197
198        mLooper = Looper.myLooper();
199        if (mLooper == null) {
200            throw new RuntimeException(
201                "Can't create handler inside thread that has not called Looper.prepare()");
202        }
203        mQueue = mLooper.mQueue;
204        mCallback = callback;
205        mAsynchronous = async;
206    }
198-202行可以看到取得了唯一一个Looper实例,然后又从Looper实例取出MessageQueue对象,所以1:1:1,这样handler就和looper和messageQueue链接一起了
然后我们来看handler.sendMessage()方法,这个方法最终调用的是
626    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
627        msg.target = this;
628        if (mAsynchronous) {
629            msg.setAsynchronous(true);
630        }
631        return queue.enqueueMessage(msg, uptimeMillis);
632    }
627行msg.target=this 把Hnalder赋值给了msg的target属性,最后 queue.enqueueMessage(msg, uptimeMillis);存到queue消息队列中,
现在我们可以看msg.target.dispatchMessage(msg)这个方法了,
93     public void dispatchMessage(Message msg) {
94         if (msg.callback != null) {
95             handleCallback(msg);
96         } else {
97             if (mCallback != null) {
98                 if (mCallback.handleMessage(msg)) {
99                     return;
100                }
101            }
102            handleMessage(msg);
103        }
104    }
会调用95行,而95行是一个空方法,要我们自己实现的
这样,handler发送消息之后,就把消息存到消息队列了,而loop开始取出消息并调用dispatchMessage,回调接口。







 
  


 
  

你可能感兴趣的:(android)