zygote服務是Android啟動和服務APK的核心服務,每個APK都是通過zygote啟動,今日閱讀它的原始碼學習到一個不錯的設計思路。

首先看看一個APK通過zygote的啟動流程:


按照一般的設計思路,既然每個APK都是由單獨的dalvik啟動和執行,那麼直接通過dalvikvm啟動main不就完了嗎?為啥還要搞得這麼長一串流程。其實關鍵就在於這個Fork。我們看看對於linux啟動一個程序的一般流程:

  1. 核心建立一個程序資料結構
  2. 核心從指定的程式檔案讀取程式程式碼並裝載到設定的記憶體地址
  3. 核心從指定的目標程式入口執行程式碼
而對於一個普通的APK來說,它需要能訪問到整個framework,所以第二步就需要裝載整個framework,這對於啟動apk這麼頻繁的操作來說是不小的效能損耗。而Fork是在本程序的基礎上直接複製出一個新的程序,並且具有相同的程序資料結構,因此只要在Fork之前zygote預先載入共享的底層資源,就省去了後面所有apk載入framework的過程。具體程式碼非常清晰簡單,可見原始碼列表:
  • /framework/base/cmds/app_process/app_main.cpp:zygote服務啟動入口
  • /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:初始化Socket服務端,並負責fork dalvik程序
  • /libcore/dalvik/src/main/java/dalvik/system/Zygote.java:包裝native fork方法
程式碼比較簡單直接,就不多解釋。這裡可以吸取的是當需要設計一個頻繁啟動程序的系統時,如果程序間有很多可以同享的程式和資料時,可以考慮通過fork來實現。