Android 主執行緒之旅——PSVM(public static void main)

發表於2015-01-30

當碰到與Android主執行緒互動相關的Bug時,我決定好好去看看Android的主執行緒究竟是怎麼一回事。這篇文章就是描述我的Android主執行緒之旅的第一部分。

PSVM

眾所周知,所有的Java程式的入口都是 public static void main() 方法。這對所有的Java 桌面程式、J2EE以及Android程式都是成立的。

當Android啟動時,它會開啟一個叫做 ZygoteInit 的Linux程式。這個程式是一個Dalvik 虛擬機器,它會在一個執行緒上面載入Android SDK裡面大部分的常用類,然後等待。

當Android啟動一個新的Android程式時,Android系統會 fork 這個ZygoteInit 程式。接著子程式裡面的執行緒會停止等待,然後呼叫ActivityThread.main()方法。

Wikipedia上面的一個Zygote。根據Wikipedia的定義,一個 Zygote 就是一個受精卵細胞。

Loopers

在繼續深入之前,我們需要來看一看Looper這個類。

使用looper可以連續地為一個執行緒處理它的訊息。

每一個looper都有一個訊息佇列(一個 MessageQueue)。

每一個looper都有一個處理訊息佇列裡面所有訊息的loop()方法,這個方法會在訊息佇列為空時阻塞。

Looper.loop() 方法裡面的程式碼類似這樣:

每一個looper都會和一個執行緒繫結。要建立一個新的looper並將它同當前的執行緒繫結起來,你必須要呼叫Looper.prepare()方法。這些looper都被儲存在Looper 類裡面的靜態ThreadLocal變數裡面。你可以通過呼叫Looper.myLooper()方法來獲取與當前執行緒相關聯的Looper。

當然實際情況不要這麼複雜,其實HandlerThread類已經幫你做了所有事情:

HandlerThread的內部程式碼類似於這樣:

Handlers

handler 天生就是 looper 的好夥伴。

一個 handler 有兩個作用:

  • 從任意執行緒傳送訊息給一個looper的訊息佇列;
  • 處理相關聯的looper發過來的訊息。

你可以為一個looper關聯多個handler。looper會把message傳送到message.target(它就是一個handler)這裡。

一個常用簡單的用法就是使用handler來傳送一個Runnable物件:

一個handler也可以在沒有設定looper的情況下被建立。:

handler的無參建構函式會呼叫方法來獲取與當前執行緒相關聯的looper。這個時候你要注意,可能當前執行緒不是你的handler想關聯的執行緒。

大部分時間,你只需要建立一個在主執行緒上面傳送訊息的handler就行了:

Back to PSVM

讓我們再來看看 ActivityThread.main()這個方法。下面就是這個方法的一些內部實現:

現在你知道為什麼這個執行緒被稱為主執行緒了吧:) .

注意: 主執行緒最先做的幾件事情之一就是建立Application物件,然後呼叫Application.onCreate()方法。

相關文章