1. 程式人生 > >[android原始碼日記]-android的主執行緒為什麼不會因為Looper.loop()裡面的死迴圈卡死?

[android原始碼日記]-android的主執行緒為什麼不會因為Looper.loop()裡面的死迴圈卡死?

一下是按照我自己的理解做的一個記錄。

顯而易見,在我們提出這個問題的時候,我們知道安卓主執行緒(又叫UI執行緒)在應用程式啟動ActivityThread的時候,就依次呼叫 Looper.prepareMainLooper(); Looper.loop();了,實際上跟我們在工作執行緒中使用Looper.prepare();Looper.loop();

ActivityThread main函式原始碼:

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"
); SamplingProfilerIntegration.start(); // 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>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); 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"); }

那就神奇了,Looper.loop()裡面是個死迴圈啊,既然主執行緒在這裡就進入了死迴圈了那後面的android生命週期還怎麼執行?

android中的主執行緒確實不會因為looper.loop()裡面的死迴圈卡死,執行緒本質上只是一段可執行的程式碼,而這串程式碼結束之後,執行緒的生命也就結束了,而android中的Looper.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;

    // Make sure the identity of this thread is that of the local process,
    // and keep track of what that identity token actually is.
    Binder.clearCallingIdentity();
    final long ident = Binder.clearCallingIdentity();

    for (;;) {
        Message msg = queue.next();
        ....
    }
}

那麼在進入死迴圈之後,又是怎麼去處理諸如點選,滑動,這些事務的呢?

那就是通過啟動一個新的執行緒來處理的:

事實上,在ActivityThread main函式中,thread.attach(false);這一行就是啟動了一個新執行緒。

public static void main(String[] args) {
        ....

        //建立Looper和MessageQueue物件,用於處理主執行緒的訊息
        Looper.prepareMainLooper();

        //建立ActivityThread物件
        ActivityThread thread = new ActivityThread();

        //建立Binder通道 (建立新執行緒)
        thread.attach(false);

        Looper.loop(); //訊息迴圈執行
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

但我看ActivityThread沒有繼承Thread啊,他不是個執行緒啊,,這個地方還不明白,先做筆記。。等看明白了回來補。