天天看點

【Android 異步操作】Handler ( 主線程中的 Handler 與 Looper | Handler 原理簡介 )

文章目錄

  • ​​一、主線程中的 Handler 與 Looper​​
  • ​​二、Handler 原理簡介​​

一、主線程中的 Handler 與 Looper

Android 系統中 , 點選圖示啟動一個應用程序 , 就是從 Linux 的 Zygote 程序 fork 一個子程序 , 之後該子程序就會建立 ActivityThread , 執行其中的 main 函數 , 該 main 函數就是應用的主線程 ;

Android 的主線程在 ActivityThread 中建立并維護 , 在該類中的 main 函數 , 就是 Activity 中的主函數 ;

在該主函數中 , 調用 Looper.prepareMainLooper() 準備主線程 Looper ;

在最後的地方調用 Looper.loop() , 無限循環消息隊列中的消息 ;

public final class ActivityThread extends ClientTransactionHandler {

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        // 擷取主線程 Handler 對應的 Looper 
        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(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // 無限循環擷取任務并執行 
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}      
​源碼參考 :​ ​​android/9.0.0_r8/xref/frameworks/base/core/java/android/app/ActivityThread.java​​

二、Handler 原理簡介

Handler 主要作用是 , 用于 線程間通信 ,

線上程

A

A

A 中建立 Handler , 在其它線程中使用 Handler 對象發送消息給

A

A

A 線程的 MessageQueue 消息隊列 ,

線程

A

A

A 中的 Looper 不停地從 消息隊列 ( MessageQueue ) 中取出 Message 消息 , 然後進行分發 ;

線上程

A

A

A 中使用 Handler , 首先要調用 Looper.prepare()方法 , 該方法的作用是準備輪詢器 ,

Looper 建立後 , 會放在 ThreadLocal 中 , 這是線程的變量表 , 每個線程都有一個線程 ThreadLocal ,

使用線程

A

A

A 時 , 拿到

A

A

A 線程的 Looper , 在其它線程中調用 Handler 的 sendMessage 方法 ,

将消息傳遞給線程

A

A

A 中的 消息隊列 ( MessageQueue ) 中 ,

Looper 中維護了一個 消息隊列 ( MessageQueue ) , MessageQueue 封裝在 Looper 中 ;

繼續閱讀