帶你讀源碼!Android研習社:技術分享第二期

前言

Android研習社第二期技術分享的錄播視頻,已經放到B站上了,你們能夠戳連接www.bilibili.com/video/av712…食用安全

這篇文章,一來是Android研習社第二期技術分享的視頻講義,二來也對上一篇的Zygote源碼分析進行了一個補充,水平有限,還請你們多多指教多線程

源碼閱讀工具

understand 5.1app

連接:pan.baidu.com/s/1sHXuTxv8… 密碼:hywc 解壓密碼:xclient.infosocket

源碼閱讀方法

  1. 如何把源碼讀起來ide

    閱讀相關技術文章,總結重要的知識點,給本身提問題,去源碼中找答案,有一個針對性工具

  2. 如何抓大放小oop

    源碼很龐大,涉及的細節和深度也比較多,要清楚本身當前,想搞懂的是什麼問題源碼分析

  3. 如何把握主要問題post

    沒有定論,多閱讀多體會,閱讀相關技術文章和讀源碼穿插結合線程

源碼領讀:Zygote源碼分析

主要問題分析:Zygote進程主要流程分析

原本的想法是分析Zygote進程是如何被啓動起來的,後來發現沒啥東西,因此今天仍是分析下Zyogte主要作了些什麼事情;目的呢,其實仍是讓你們知道如何去讀源碼,正所謂授人以漁,不如授人以漁

請戳連接食用:www.bilibili.com/video/av712…

再談Zygote,由厚到薄

Zygote進程的啓動都經歷了哪些流程

咱們先來大概梳理下Zygote進程的啓動都經歷了哪些流程

如上手稿所示,首先呢,init進程須要對相關腳本進行解析,根據設備的不一樣,可能會解析不一樣的腳本文件,好比32位設備就是32爲的zygote腳本,腳本中又根據設備的不一樣,可能會有兩個zygote來分別對32位應用和64位應用進行fork。

深刻分析

爲何要使用腳本

咱們來考慮下,這裏爲何要使用腳本,同時又要搞一套腳本解析的邏輯,來對zygote進行初始化呢?若是寫死到邏輯裏,是否能夠呢?這裏咱們先留一個問號,先接着往下分析

經過對腳本的解析,咱們執行app_process的二進制文件開啓一個進程,並把這個進程名改成zygote,而後對該進程進行初始化操做,這裏咱們還須要進一步分析,初始化過程當中,究竟作了什麼事情;

最後,進入一個死循環,用socket通訊來接收子進程發送過來的消息,這裏的socket是服務端,其餘進程至關於客戶端,因此代碼中命名爲ZygoteServer,就是這個意思

在這個死循環中,使用了多路IO複用的機制(select機制),這個也須要去進一步分析

進入死循環後,至關於當前進程一直處於運行狀態,那麼咱們也要接着去執行下面的邏輯呀,不能卡死在這裏呀,因此咱們又fork出一個重要進程,SystemServer,由這個進程去開啓一系列的系統服務,好比AMS,PMS,WMS,這些系統服務都是跑在一個進程下的(這個須要進一步確認),由這些系統服務提供一些公共的東西給其餘進程來調度和使用

爲何這麼設計

這麼設計的緣由,咱們來簡單的猜想下。若是沒有這些系統服務,那咱們如何去調度系統資源呢?每一個進程都須要主動找系統層去要,那麼系統層就要把這些邏輯,好比跨進程的消息處理,多線程的安全問題,都要寫在複雜的邏輯中去。若是把這些邏輯抽離出來,一來,至關於收攏了相關功能的處理權限;二來,各個服務職責單一,也簡化了代碼,提高了代碼的可閱讀性和可維護性

另外,爲何要單開一個進程來維護這些系統服務呢?就算我調用了runSelectLoop()進入了死循環,那其實還能夠另開一個線程啊!

我以爲這個就是跟總體的設計相關了,好比說,我們作一個項目,其中有一個模塊是相對獨立的,跟其餘業務是沒有什麼關係的,好比音視頻播放,或者Webview展現H5頁面,相似的功能,那咱們其實通常是會單獨開啓一個子進程的。我以爲系統層面的設計也有相似的考慮,若是zygote進程出了問題,那就從新初始化zygote就好了,若是在init進程出了問題,就針對init作單獨的業務處理,保證他們互相的獨立性,和業務上的解耦,互相都不會影響;若是是開啓一個線程,就可能須要處理各類各樣的問題

SystemServer,能夠說是Java世界的頭號進程--Zygote--誕生一來,fork出來的第一個子進程,這個fork出的進程,內部是如何設計的,如何維護這個系統服務的,這個也是咱們接下來的SystemServer源碼要分析的部分

咱們再來探討下,Zygote爲何要設計一個跟子進程通訊的ZygoteServer,上面咱們也提到了,它內部是維護了兩個Socket對象,zygoteSocketuaspSocket,那麼咱們就要了解,Linux中,經典跨進程通訊的方案有哪些了。Socket是進程間通訊的一種方式,並且,是能夠無視Native世界和Java世界的。也能夠說,它是一種協定好的通訊方案。像咱們以前作的遊戲輔助應用,咱們須要經過adb來開啓一個native進程,這個進程又是須要跟App所在的進程進行通訊的,那麼,在這種場景下,咱們就是使用了Socket通訊的方式,一個做爲server端,一個做爲client端,進行數據的傳遞。

Zygote進程,是由init進程經過執行exec(須要確認)的系統調用開啓的,它是溝通Java世界和native世界的橋樑,zygote進程最終是在Java世界中的,這裏咱們的zygote跟它的子進程通訊,也須要一個一對多的數據通訊設計(一個Zyogte會fork出多個子進程)。

爲何要有一個母體

我這裏還想談一談,爲何要設計有一個母體,fork出子進程這種進程的運行方式。有一些資源是能夠共享的,好比VM的運行環境,那麼我想再開啓一個子進程,又想同時對VM的運行環境進行復用,這麼來看,fork出一個子進程,是一個比較好的方式;同時,32位的zygote和64位的zygote須要在不一樣的VM環境下運行,因此纔會有兩個zygote--primeryZygotesecondZygote

那麼什麼又是VM呢?簡單來說,就是運行環境,這個運行環境不是硬件層的,而是軟件層面的,好比像咱們開發App,也須要又SDK,NDK之類的工具包,才能進行開發。VM也是同理,提供一些共有的環境,供進程來使用,好比各自的私有目錄,進程及進程組的權限,等等

接下來要作的事

  1. SystemServer源碼分析(下週)
  2. 系統啓動流程總體分析(下下週?)
  3. 10分鐘搞定源碼,系列短視頻(下下下週?)
  4. 源碼動態調試(待定)

寫在最後

原創不易,堅持更難。 若是你想繼續看到我接下來的分享,請經過點讚的方式告訴我,你的鼓勵是我繼續創做的最大動力!

鄭重聲明

本文由Android研習社社羣創做,版權©️歸Android研習社全部,侵權必究!

相關文章
相關標籤/搜索