Handler

创建一个 Handler handler = new Handler();

public Handler() { this(null, false); }

【Handler】初始化looper 与 handler
/** * Use the {@link Looper} for the current thread with the specified callback interface * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages.Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { //handler 应为static 修饰,否会有内存泄漏 Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } }mLooper = Looper.myLooper(); //获取主线程的looper if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }

//从ThreadLocal 获取looper
/** * Return the Looper object associated with the current thread.Returns * null if the calling thread is not associated with a Looper. */ public static @Nullable Looper myLooper() { return sThreadLocal.get(); }/** * Returns the value in the current thread's copy of this * thread-local variable.If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); } /** * Variant of set() to establish initialValue. Used instead * of set() in case user has overridden the set() method. * * @return the initial value */ private T setInitialValue() { T value = https://www.it610.com/article/initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); return value; }

UI Handler 初始化,looper的开始轮询 Activity--->ActivityThread&main()
#ActivityThread public static void main(String[] args) { Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { //ActivityThread //final H mH = new H(); sMainThreadHandler = thread.getHandler(); }if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); }// End of event ActivityThreadMain. Looper.loop(); }

Looper&prepareMainLooper()
创建UI线程Looper
#Looper#/** * Initialize the current thread as a looper, marking it as an * application's main looper. The main looper for your application * is created by the Android environment, so you should never need * to call this function yourself.See also: {@link #prepare()} */ public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } //创建looper 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)); //创建looper,并缓存到ThreadLocal;key:Thread, value :Looper }private Looper(boolean quitAllowed) { //创建MessageQueue mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }/** * Return the Looper object associated with the current thread.Returns * null if the calling thread is not associated with a Looper. */ public static @Nullable Looper myLooper() { //从ThreadLocal取 looper return sThreadLocal.get(); }

Handler & sendMessage()原理
//列子 private static Handler handler = new Handler(){ public void handleMessage(android.os.message msg){ } } handler.setEmptyMessage(what);

/** * Sends a Message containing only the what value. * * @return Returns true if the message was successfully placed in to the *message queue.Returns false on failure, usually because the *looper processing the message queue is exiting. */ public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0); } /** * Sends a Message containing only the what value, to be delivered * after the specified amount of time elapses. * @see #sendMessageDelayed(android.os.Message, long) * * @return Returns true if the message was successfully placed in to the *message queue.Returns false on failure, usually because the *looper processing the message queue is exiting. */ public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); }/** * Enqueue a message into the message queue after all pending messages * before (current time + delayMillis). You will receive it in * {@link #handleMessage}, in the thread attached to this handler. * * @return Returns true if the message was successfully placed in to the *message queue.Returns false on failure, usually because the *looper processing the message queue is exiting.Note that a *result of true does not mean the message will be processed -- if *the looper is quit before the delivery time of the message *occurs then the message will be dropped. */ public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }/** * Enqueue a message into the message queue after all pending messages * before the absolute time (in milliseconds) uptimeMillis. * The time-base is {@link android.os.SystemClock#uptimeMillis}. * Time spent in deep sleep will add an additional delay to execution. * You will receive it in {@link #handleMessage}, in the thread attached * to this handler. * * @param uptimeMillis The absolute time at which the message should be *delivered, using the *{@link android.os.SystemClock#uptimeMillis} time-base. * * @return Returns true if the message was successfully placed in to the *message queue.Returns false on failure, usually because the *looper processing the message queue is exiting.Note that a *result of true does not mean the message will be processed -- if *the looper is quit before the delivery time of the message *occurs then the message will be dropped. */ public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); } private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; //msg.target=handler if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }

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=handler //handler.dispatchMessage(msg) msg.target.dispatchMessage(msg); } finally {}/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) {//重写Callback(),可以拦截handleMessage() if (mCallback.handleMessage(msg)) { return; } } //handler处理消息 handleMessage(msg); } } }

    推荐阅读