美文网首页
Handler机制

Handler机制

作者: Tony__Ren | 来源:发表于2019-04-11 20:37 被阅读0次

    handle 首先想到的是和线程的关系。

    • 来看一下官方源码。
    //ActivityThread中的main方法
       Looper.prepareMainLooper();
    
      // Find the value for {@link #PROC_START_SEQ_IDENT} if provided   on the command line.
      // It will be in the format "seq=114"
      long startSeq = 0;
      if (args != null) {
        for (int i = args.length - 1; i >= 0; --i)
      {
          if (args[i] != null &&args[i].startsWith(PROC_START_SEQ_IDENT)) {
               startSeq = Long.parseLong(
               args[i].substring(PROC_START_SEQ_IDENT.length()));
                      }
             }
      }
      ActivityThread thread = new ActivityThread();
      thread.attach(false, startSeq);
      if (sMainThreadHandler == null) {
              sMainThreadHandler = thread.getHandler();
      }
      if (false) 
      {
       Looper.myLooper().setMessageLogging(newLogPrinter(
              Log.DEBUG, "ActivityThread"));
      }
    
      // End of event ActivityThreadMain.
      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
      Looper.loop();
    
    
    • 再来看一下Looper中的方法
    /**
         * Run the message queue in this thread. Be sure to call
         * {@link #quit()} to end the 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;
              ......
            for (;;) {
                Message msg = queue.next(); // might block
                if (msg == null) {
                    // No message indicates that the message queue is quitting.
                    return;
                }
    
               ......
               
                try {
                    msg.target.dispatchMessage(msg);
                    dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
                } finally {
                    if (traceTag != 0) {
                        Trace.traceEnd(traceTag);
                    }
                }
               ......
    
                msg.recycleUnchecked();
            }
        }
    

    里面起了个死循环不断的重MessageQueue中取出Message,msg.target其实就是Handler。

    • 看一下prepareMainLooper()中干了什么事情?
        static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
        private static Looper sMainLooper;  // guarded by Looper.class
    
        final MessageQueue mQueue;
        final Thread mThread;
    
        public static void prepareMainLooper() {
            prepare(false);
            synchronized (Looper.class) {
                if (sMainLooper != null) {
                    throw new IllegalStateException("The main Looper has already been prepared.");
                }
                sMainLooper = myLooper();
            }
        }
        public static void prepare() {
            prepare(true);
        }
        public static @Nullable Looper myLooper() {
            return sThreadLocal.get();
        }
        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));
        }
    

    到这里我们很清楚了,是通过ThreadLocal绑定线程的。这里的ThreadLocal是一个键值对的结构体。通过静态的prepare方法保证线程安全,每个线程只能绑定一个Looper。

    • 再来看一下msg.target.dispatchMessage(msg)这个方法的源码。
    /**
         * Subclasses must implement this to receive messages.
         */
      public void handleMessage(Message msg) {
        }
        
        /**
         * Handle system messages here.
         */
      public void dispatchMessage(Message msg) {
            if (msg.callback != null) {
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
      private static void handleCallback(Message message) {
            message.callback.run();
        }
    

    这里很明显看出dispatchMessage先调用msg中callback方法,其次调用Handler自己的Callback,最后调用handleMessage方法。

    相关文章

      网友评论

          本文标题:Handler机制

          本文链接:https://www.haomeiwen.com/subject/bwnziqtx.html