Handler机制

2019-04-11  本文已影响0人  Tony__Ren

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();

/**
     * 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。

    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。

/**
     * 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方法。

上一篇下一篇

猜你喜欢

热点阅读