android-源碼篇-Handler

背景

有時候需要在子線程中進行耗時的 I/O 操作,讀取文件或者訪問網絡等,當耗時操作完成以後可能需要在 UI 上做一些改變,由於 Android 開發規範的限制,不能在子線程中訪問 UI 控件,否則就會觸發程序異常,這個時候通過 Handler 就可以將更新 UI 的操作切換到主線程中執行。

相關類

  • Handler
  • Looper(消息循環)
  • Message(消息)
  • MessageQueue(存儲消息)

Handler

package android.os;
public class Handler
public Handler(Callback callback, boolean async) {
    ...// 省略其他代碼
    
    // 獲取當前線程的 Looper 對象,如果沒有則拋出異常
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread " + Thread.currentThread()
                    + " that has not called Looper.prepare()");
    }
    // 綁定消息隊列對象
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

創建 Handler 對象時,自動關聯當前線程的 Looper 對象,綁定相應的消息隊列對象。

Looper

package android.os;
public final class Looper

// Looper初始化
public static void prepare() 
// 消息循環
public static void loop()
// ThreadLocal<Looper> sThreadLocal = new ThreadLocal<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));
}

private Looper(boolean quitAllowed) {
	// 創建消息隊列對象,當創建Looper實例時,會自動創建與之關聯的消息隊列實例
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

FAQ

android 主線程中 Looper.loop() 爲什麼不會造成程序 ANR?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章