android中的Looper实现机制

     Looper类是android系统中重要的类,用于处理android线程方面的应用。它的主要作用是初始化MessageQueue类,并且分配消息的处理。Looper类的源码非常简短,可以好好的分析一下源码:

  private static final String TAG = "Looper";

    // sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static Looper sMainLooper;  // guarded by Looper.class

    final MessageQueue mQueue;
    final Thread mThread;
    volatile boolean mRun;

    private Printer mLogging;

   在这些成员变量中,最重要的属性分别是sThreadLocal和mQueue,sThreadLocal是ThreadLocal类型的变量,对于这个ThreadLocal类型,正确的理解应该是ThreadLocalVariable,是一个线程本地化的变量,对于这个对象在每个线程中都像是拥有单独的变量一样,这样多个线程之间就不会产生竞争关系。mQueue是一个MessageQueue对象,暂时可以理解是一个阻塞队列,后面再去详细介绍。那么对于非UI线程的线程,使用Looper的第一步都是Looper.prepare()方法,那么这个方法都做了什么呢?

 public static void prepare() {
        prepare(true);
    }

    
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
    
    
     private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mRun = true;
        mThread = Thread.currentThread();
    }

   在这个方法中,我们可以清楚看到Looper设置了sThreadLocal的值和初始化了MessageQueue。接下来调用的是Looper.loop()方法。

   

 public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            msg.target.dispatchMessage(msg);

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {
                Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycle();
        }
    }

   在这个方法中,Looper首先是取出来一个本地化线程下的Looper对象,然后取出该对象中的MessageQueue。然后在for(;;;)语句中循环去取出MessageQueue中的Message对象,然后调用message.target对象的dispatchMessage()方法分发消息,此时的target对象就是一个Handler对象。所以对于Looper类的理解就是:初始化一个MessageQueue和一个本地化变量的Looper,这样handler类就可以通过sendMessage等方法将消息添加到MessageQueue中,并且通过looper方法将消息不断的取出分发到对应的handler去处理。



你可能感兴趣的:(android中的Looper实现机制)