@yudesong
2018-02-12T03:12:13.000000Z
字数 2542
阅读 622
Handler
正如郭大神所说的那样:
Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃。相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟于心,即创建一个Message对象,然后借助Handler发送出去,之后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作就不会再出现崩溃了。
首先,来看看Handle的源码
public Handler() {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass()|| klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should bestatic or leaks might occur: " +klass.getCanonicalName());}}mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread thathas not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = null;}public static final void prepare() {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper());}public static final Looper myLooper() {return (Looper)sThreadLocal.get();}
接下来看看Handler是如何传递消息的
public boolean sendMessageAtTime(Message msg, long uptimeMillis){boolean sent = false;MessageQueue queue = mQueue;if (queue != null) {msg.target = this;sent = queue.enqueueMessage(msg, uptimeMillis);}else {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);}return sent;}final boolean enqueueMessage(Message msg, long when) {if (msg.when != 0) {throw new AndroidRuntimeException(msg+ " This message is already in use.");}if (msg.target == null && !mQuitAllowed) {throw new RuntimeException("Main thread not allowed to quit");}synchronized (this) {if (mQuiting) {RuntimeException e = new RuntimeException(msg.target+ " sending message to a Handler on a dead thread");Log.w("MessageQueue", e.getMessage(), e);return false;} else if (msg.target == null) {mQuiting = true;}msg.when = when;Message p = mMessages;if (p == null || when == 0 || when < p.when) {msg.next = p;mMessages = msg;this.notify();} else {Message prev = null;while (p != null && p.when <= when) {prev = p;p = p.next;}msg.next = prev.next;prev.next = msg;this.notify();}}return true;}public static final void loop() {Looper me = myLooper();MessageQueue queue = me.mQueue;while (true) {Message msg = queue.next(); // might blockif (msg != null) {if (msg.target == null) {return;}if (me.mLogging!= null) me.mLogging.println(">>>>> Dispatching to " + msg.target + " "+ msg.callback + ": " + msg.what);msg.target.dispatchMessage(msg);if (me.mLogging!= null) me.mLogging.println("<<<<< Finished to " + msg.target + " "+ msg.callback);msg.recycle();}}}public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}