Looper 源码分析

 
 
    //可以看到我们的Looper是存放在线程独有的ThreadLocal进行隔离的
    //也就是每个线程独有一份Looper
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    //系统帮我们实现的主线程的Looper对象
    private static Looper sMainLooper;
    //每一个Looper都有自己的MessageQueue消息队列
    final MessageQueue mQueue;
    final Thread mThread;
    
  *  class LooperThread extends Thread {
  *      public Handler mHandler;
  *
  *      public void run() {
  *          Looper.prepare();
  *
  *          mHandler = new Handler() {
  *              public void handleMessage(Message msg) {
  *                  // process incoming messages here
  *              }
  *          };
  *
  *          Looper.loop();
  *      }
  *  }
  这个是Looper开篇的使用示例
  我们在使用Handler机制的时候需要创建一个Looper对象利用Looper里面的MessageQueue消息队列
  来存放我们发送的Message消息Message消息里面存有我们发送的数据、延迟时间、回调方法等。
  这样在looper进行轮询消息队列的时候就能够将里面的Message交给对应的Handler去处理。
 
  在子线程中:
  Looper.prepare();是用来创建一个Looper的
  源码:
      public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        //从ThreadLocal去拿我们的Looper 如果已经存在了就抛出异常
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        //否则就创建一个looper对象并放在ThreadLocal中存储
        sThreadLocal.set(new Looper(quitAllowed));
    }
   new Looper(quitAllowed)    源码:
   
    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
  可以看到    在创建Looper的时候也会创建一个MessageQueue消息队列
     
     //主线程的Looper创建----系统会在ActivityThread的main()方法里面调用这个方法进行创建的
     public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }
    
        * 源码分析:main()
        **/
        public static void main(String[] args) {
        

            Looper.prepareMainLooper();
            // 1. 为主线程创建1个Looper对象,同时生成1个消息队列对象(MessageQueue)
            // 方法逻辑类似Looper.prepare()
            // 注:prepare():为子线程中创建1个Looper对象
            
            
            ActivityThread thread = new ActivityThread();
            // 2. 创建主线程

            Looper.loop();
            // 3. 自动开启 消息循环 ->>下面将详细分析

        }    
    
        loop()    源码
    
        public static void loop() {
        //获取当前线程的Looper对象
        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();

        // Allow overriding a threshold with a system prop. e.g.
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        final int thresholdOverride =
                SystemProperties.getInt("log.looper."
                        + Process.myUid() + "."
                        + Thread.currentThread().getName()
                        + ".slow", 0);

        boolean slowDeliveryDetected = false;

        for (;;) {
        // 从MessageqQueue里面去拿消息 这个过程会随着message取完后阻塞
            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
            final Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            final long traceTag = me.mTraceTag;
            long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
            long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;
            if (thresholdOverride > 0) {
                slowDispatchThresholdMs = thresholdOverride;
                slowDeliveryThresholdMs = thresholdOverride;
            }
            final boolean logSlowDelivery = (slowDeliveryThresholdMs > 0) && (msg.when > 0);
            final boolean logSlowDispatch = (slowDispatchThresholdMs > 0);

            final boolean needStartTime = logSlowDelivery || logSlowDispatch;
            final boolean needEndTime = logSlowDispatch;

            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }

            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
            final long dispatchEnd;
            try {
                //取出的消息会交给对应的Handler去处理
                msg.target.dispatchMessage(msg);
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            if (logSlowDelivery) {
                if (slowDeliveryDetected) {
                    if ((dispatchStart - msg.when) <= 10) {
                        Slog.w(TAG, "Drained");
                        slowDeliveryDetected = false;
                    }
                } else {
                    if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
                            msg)) {
                        // Once we write a slow delivery log, suppress until the queue drains.
                        slowDeliveryDetected = true;
                    }
                }
            }
            if (logSlowDispatch) {
                showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", 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.recycleUnchecked();
        }
    }
    
  总结:Looper实际是利用ThreadLocal和线程进行绑定的,通过内部维护的一个消息队列来存储格格Handler发送过来的Message

 实现线程间通信的 
    
    
    
    
    
    
    
    
    
    
    
    
    
   

猜你喜欢

转载自www.cnblogs.com/lianzhen/p/12926737.html