Android系統開篇
一、引言
Android系統非常龐大、錯綜複雜,其底層是採用Linux
作為基底,上層採用包含虛擬機器的Java層以及Native
層,通過系統呼叫(Syscall)連通系統的核心空間與使用者空間。使用者空間主要採用C++和Java程式碼,通過JNI
技術打通使用者空間的Java層和Native
層(C++/C),從而融為一體。
Google官方提供了一張經典的四層架構圖,從下往上依次分為Linux核心、系統庫和Android執行時環境、框架層以及應用層這4層架構,其中每一層都包含大量的子模組或子系統。這只是如壘磚般地分層,並沒有表達Android整個系統的內部架構、執行機理,以及各個模組之間是如何銜接與配合工作的。為了更深入地掌握Android整個架構思想以及各個模組在Android系統所處的地位與價值,計劃以Android
系統啟動過程為主線,以程式的視角來詮釋Android M系統全貌,全方位的深度剖析各個模組功能,爭取各個擊破。這樣才能猶如庖丁解牛,解決、分析問題則能遊刃有餘。
android-arch1
二、Android架構
Google提供的4層架構圖很經典,但為了更進一步透視Android系統架構,本文更多的是以程式的視角,以分層的架構來詮釋Android系統的全貌,闡述Android內部的環環相扣的內在聯絡。
系統啟動架構圖
圖解: Android系統啟動過程由上圖從下往上的一個過程:Loader -> Kernel -> Native -> Framework -> App
,接來下簡要說說每個過程:
2.1 Loader層
Boot ROM
: 當手機處於關機狀態時,長按Power鍵開機,引導晶片開始從固化在ROM裡的預設出程式碼開始執行,然後載入載入程式到RAM;
Boot Loader
:這是啟動Android系統之前的載入程式,主要是檢查RAM
,初始化硬體引數等功能。
2.2 Kernel層
Kernel
層是指Android核心層,到這裡才剛剛開始進入Android系統。
啟動Kernel
的swapper
程式(pid=0
):該程式又稱為idle
程式, 系統初始化過程Kernel由無到有開創的第一個程式, 用於初始化程式管理、記憶體管理,載入Display,Camera Driver,Binder Driver
等相關工作;
啟動kthreadd
程式(pid=2
):是Linux系統的核心程式,會建立核心工作執行緒kworkder
,軟中斷執行緒ksoftirqd
,thermal
等核心守護程式。kthreadd
程式是所有核心程式的鼻祖。
2.3 Native層
這裡的Native
層主要包括init
孵化來的使用者空間的守護程式、HAL
層以及開機動畫等。啟動init
程式(pid=1
),是Linux系統的使用者程式,init
程式是所有使用者程式的鼻祖。
init
程式會孵化出ueventd、logd、healthd、installd、adbd、lmkd
等使用者守護程式;init
程式還啟動servicemanager
(binder
服務管家)、bootanim
(開機動畫)等重要服務init
程式孵化出Zygote
程式,Zygote
程式是Android系統的第一個Java
程式(即虛擬機器程式),Zygote
是所有Java
程式的父程式,Zygote
程式本身是由init
程式孵化而來的。
2.4 Framework
層
Zygote
程式,是由init
程式通過解析init.rc
檔案後fork
生成的,Zygote
程式主要包含:
- 載入
ZygoteInit
類,註冊Zygote Socket
服務端套接字; - 載入虛擬機器;
preloadClasses
;preloadResouces
。
System Server
程式,是由Zygote
程式fork
而來,System Server
是Zygote
孵化的第一個程式,System Server
負責啟動和管理整個Java framework
,包含ActivityManager
,PowerManager
等服務。
Media Server
程式,是由init
程式fork
而來,負責啟動和管理整個C++ framework
,包含AudioFlinger
,Camera Service
,等服務。
2.5 App層
Zygote
程式孵化出的第一個App
程式是Launcher
,這是使用者看到的桌面App
;
Zygote
程式還會建立Browser
,Phone
,Email
等App
程式,每個App
至少執行在一個程式上。
所有的App
程式都是由Zygote
程式fork
生成的。
2.6 Syscall
&& JNI
Native
與Kernel
之間有一層系統呼叫(SysCall
)層,見Linux系統呼叫(Syscall
)原理;
Java層與Native
(C/C++)層之間的紐帶JNI
,見Android JNI
原理分析。
三、通訊方式
無論是Android系統,還是各種Linux衍生系統,各個元件、模組往往執行在各種不同的程式和執行緒內,這裡就必然涉及程式/執行緒之間的通訊。對於IPC
(Inter-Process Communication
, 程式間通訊),Linux現有管道、訊息佇列、共享記憶體、套接字、訊號量、訊號這些IPC
機制,Android額外還有Binder IPC
機制,Android OS中的Zygote
程式的IPC
採用的是Socket
機制,在上層system server、media server
以及上層App之間更多的是採用Binder IPC
方式來完成跨程式間的通訊。對於Android上層架構中,很多時候是在同一個程式的執行緒之間需要相互通訊,例如同一個程式的主執行緒與工作執行緒之間的通訊,往往採用的Handler
訊息機制。
想深入理解Android核心層架構,必須先深入理解Linux現有的IPC
機制;對於Android上層架構,則最常用的通訊方式是Binder、Socket、Handler
,當然也有少量其他的IPC
方式,比如殺程式Process.killProcess()
採用的是signal
方式。下面說說Binder、Socket、Handler
:
3.1 Binder
Binder
作為Android系統提供的一種IPC
機制,無論從系統開發還是應用開發,都是Android系統中最重要的組成,也是最難理解的一塊知識點,想了解為什麼Android要採用Binder
作為IPC
機制? 可檢視我在知乎上的回答。深入瞭解Binder
機制,最好的方法便是閱讀原始碼,借用Linux鼻祖Linus Torvalds曾說過的一句話:Read The Fucking Source Code
。下面簡要說說Binder IPC
原理。
Binder IPC原理
Binder
通訊採用c/s架構,從元件視角來說,包含Client、Server、ServiceManager
以及binder
驅動,其中ServiceManager
用於管理系統中的各種服務。
ServiceManager
想進一步瞭解Binder
,可檢視Binder
系列—開篇,Binder
系列花費了13篇文章的篇幅,從原始碼角度出發來,講述Driver、Native、Framework、App
四個層面的整個完整流程。根據有些讀者反饋這個系列還是不好理解,這個binder
涉及的層次跨度比較大,知識量比較廣, 建議大家先知道binder
是用於程式間通訊,有個大致概念就可以.先去學習系統基本知識,等後面有一定功力再進一步深入研究Binder
.
原理篇
序號 | 文章名 | 概述 |
---|---|---|
0 | Binder系列—開篇 | 概述Binder |
1 | Binder系列3—啟動Service Manager | ServiceManager守護程式 註冊和查詢服務 |
2 | Binder系列4—獲取Service Manager | 獲取代理物件BpServiceManager |
3 | Binder系列5—註冊服務(addService) | 註冊Media服務 |
4 | Binder系列6—獲取服務(getService) | 獲取Media代理,以及DeathRecipient |
5 | Binder系列7—framework層分析 | framework層服務註冊和查詢,Binder註冊 |
6 | Binder系列—理解Binder執行緒池的管理 | Binder的startThreadPool過程 |
7 | Binder系列—徹底理解Android Binder通訊架構 | startService為主線 |
8 | Binder系列10—總結 | Binder的簡單總結 |
9 | Binder IPC的許可權控制 | clearCallingIdentity/restoreCallingIdentity |
驅動篇:
序號 | 文章名 | 概述 |
---|---|---|
1 | Binder系列1—Binder Driver初探 | 驅動open/mmap/ioctl,以及binder結構體 |
2 | Binder系列2—Binder Driver再探 | Binder通訊協議,記憶體機制 |
使用篇:
序號 | 文章名 | 概述 |
---|---|---|
1 | Binder系列8—如何使用Binder | Native層、Framwrok層自定義Binder服務 |
2 | Binder系列9—如何使用AIDL | App層自定義Binder服務 |
3.2 Socket
Socket
通訊方式也是C/S
架構,比Binder
簡單很多。在Android系統中採用Socket
通訊方式的主要:
zygote
:用於孵化程式,系統程式system_server
孵化程式時便通過socket
向zygote
程式發起請求;installd
:用於安裝App的守護程式,上層PackageManagerService
很多實現最終都是交給它來完成;lmkd
:lowmemorykiller
的守護程式,Java層的LowMemoryKiller
最終都是由lmkd
來完成;adbd
:這個也不用說,用於服務adb
;logcatd
:這個不用說,用於服務logcat
;vold
:即volume Daemon
,是儲存類的守護程式,用於負責如USB
、Sdcard
等儲存裝置的事件處理。
等等還有很多,這裡不一一列舉,Socket
方式更多的用於Android framework
層與native
層之間的通訊。Socket
通訊方式相對於binder
非常簡單,所以一直沒有寫相關文章,為了成一個體系,下次再補上。
3.3 Handler
Binder/Socket
用於程式間通訊,而Handler
訊息機制用於同程式的執行緒間通訊,Handler
訊息機制是由一組MessageQueue、Message、Looper、Handler
共同組成的,為了方便且稱之為Handler
訊息機制。
有人可能會疑惑,為何Binder/Socket
用於程式間通訊,能否用於執行緒間通訊呢?答案是肯定,對於兩個具有獨立地址空間的程式通訊都可以,當然也能用於共享記憶體空間的兩個執行緒間通訊,這就好比殺雞用牛刀。接著可能還有人會疑惑,那handler
訊息機制能否用於程式間通訊?答案是不能,Handler
只能用於共享記憶體地址空間的兩個執行緒間通訊,即同程式的兩個執行緒間通訊。很多時候,Handler
是工作執行緒向UI
主執行緒傳送訊息,即App應用中只有主執行緒能更新UI
,其他工作執行緒往往是完成相應工作後,通過Handler
告知主執行緒需要做出相應地UI更新操作,Handler
分發相應的訊息給UI
主執行緒去完成,如下圖:
handler_communication
由於工作執行緒與主執行緒共享地址空間,即Handler
例項物件mHandler
位於執行緒間共享的記憶體堆上,工作執行緒與主執行緒都能直接使用該物件,只需要注意多執行緒的同步問題。工作執行緒通過mHandler
向其成員變數MessageQueue
中新增新Message
,主執行緒一直處於loop()
方法內,當收到新的Message
時按照一定規則分發給相應的handleMessage()
方法來處理。所以說,而Handler
訊息機制用於同程式的執行緒間通訊的核心是執行緒間共享記憶體空間,而不同程式擁有不同的地址空間,也就不能用handler
來實現程式間通訊。
上圖只是Handler訊息機制的一種處理流程,是不是隻能工作執行緒向UI主執行緒發訊息呢,其實不然,可以是UI執行緒向工作執行緒傳送訊息,也可以是多個工作執行緒之間通過handler傳送訊息。更多關於Handler訊息機制文章:
Android訊息機制-Handler(framework篇)
Android訊息機制-Handler(native篇)
Android訊息機制3-Handler(實戰)
要理解framework
層原始碼,掌握這3種基本的程式/執行緒間通訊方式是非常有必要,當然Linux還有不少其他的IPC
機制,比如共享記憶體、訊號、訊號量,在原始碼中也有體現,如果想全面徹底地掌握Android系統,還是需要對每一種IPC
機制都有所瞭解。
四、核心提綱
2016年新的一年剛開始,首先祝大家、也祝自己在新的一年諸事順心,事業蒸蒸日上。在過去的一年,對於Android從底層一路到上層有不少自己的理解和沉澱,但總體較零散,未成體系。藉著今天(元旦假日的最後一天),給自己的新的一年提前做一個計劃,把知識進行歸檔整理與再學習,從而加深對Android
架構的理解。通過前面對系統啟動的介紹,相信大家對Android系統有了一個整體觀,接下來需要抓核心、理思路,爭取各個擊破。
計劃:不少文章還沒來得及進一步加工,大篇章的原始碼,有讀者跟我反饋看著發睏,先別急,文章還會不斷更新和升級。前期計劃先將系統所有核心技術點的邊整理邊寫部落格; 後期工作有時間再根據大家的反饋以及自己的校驗,再不斷修正和完善所有文章,爭取給文章,再進一步精簡非核心程式碼,增加視覺化圖表以及文字的結論性分析。
部落格定位: 基於Android 6.0的原始碼,專注於分享Android系統原理、架構分析的原創文章。
建議閱讀群體: 適合於正從事或者有興趣研究Android系統的工程師或者愛好者,也適合Android app高階工程師; 對於尚未入門或者剛入門的app程式設計師閱讀可能會困難些,可能不是很適合。
看到Android整個系統架構是如此龐大的, 該問如何學習Android系統, 以下是我自己琢磨的Android的學習和研究論,僅供參考:如何自學Android.
4.1 系統啟動系列
android-booting
Android系統啟動-概述: Android系統中極其重要程式:init, zygote, system_server, servicemanager
程式:
再來看看守護程式(程式名一般以d
為字尾,比如logd
), 先介紹以下部分,字尾再增加.
debuggerd
installd
lmkd
4.2 系統穩定性系列
Android系穩定性主要是異常崩潰(crash
)和執行超時(timeout
), Android系統穩定性簡述 :
4.3 Android程式系列
程式對於系統非常重要,系統運轉,各種服務、元件的載體都依託於程式,對程式理解越深刻,越能掌握系統整體架構。那麼先來看看程式相關:
4.4 四大元件系列
對於App來說,Android應用的四大元件Activity,Service,Broadcast Receiver,Content Provider
最為核心,接下分別展開介紹:
4.5 圖形系統系列
圖形也是整個系統非常複雜且重要的一個系列,涉及WindowManager
,SurfaceFlinger
.
4.6 系統服務篇
再則就是在整個架構中有大量的服務,都是基於Binder
來互動的,計劃針對部分核心服務來重點分析:
4.7 記憶體&&儲存篇
4.8 工具篇
最後,說說Android相關的一些常用命令和工具以及除錯手段.
五、結束語
計劃: 後續持續新增和完善整個大綱,不限於程式、記憶體、IO、系統服務框架,整體架構以及各種系統分析實戰等文章。 部落格會持續更新,各個擊破,本文最近更新時間點: 2017.09.03.
相關文章
- Android 12(S) 圖形顯示系統 - 開篇Android
- Simpleperf分析之Android系統篇Android
- Android 系統開發_啟動階段篇 — 深入鑽研 SystemServerAndroidServer
- Android 系統開發_啟動階段篇 — 深入鑽研 initAndroid
- Android 儲存系統之原始碼篇Android原始碼
- Android 儲存系統之架構篇Android架構
- 測試開發之系統篇-常用系統命令
- Android系統開發開班了Android
- Linux 作業系統!開篇!!!Linux作業系統
- 開發Android系統應用Android
- Android開啟系統設定Android
- Android系統開發小記:DreamServiceAndroid
- Android Media Framework - 開篇AndroidFramework
- Android系統移植與驅動開發Android
- 【Android系統】Android系統架構簡介Android架構
- 測試開發之系統篇-Docker常用操作Docker
- 建站篇-使用者認證系統-開始
- Android學習系列(39)--Android主題和樣式之系統篇(上)Android
- Android學習系列(40)--Android主題和樣式之系統篇(下)Android
- Android原始碼解析(一)動畫篇-- Animator屬性動畫系統Android原始碼動畫
- Android開發之道(2)系統體系結構概要Android
- 系統呼叫篇——SSDT
- Android外掛化開篇Android
- Flutter混合開發—Android篇FlutterAndroid
- Android 面試開源框架篇Android面試框架
- Android系統架構-----Android的系統體系架構Android架構
- 承接上一篇,whale系統開篇,聊聊使用者認證
- 測試開發之系統篇-Docker容器安裝Docker
- Kotlin基礎篇——從型別系統開始Kotlin型別
- 【Android】1:Android APP開發入門篇AndroidAPP
- Android系統流程Android
- Android系統全貌Android
- Flutter外掛開發---Android篇FlutterAndroid
- android開源專案【developer篇】AndroidDeveloper
- crmeb 電商系統前端篇前端
- 作業系統篇-cpu作業系統
- 推薦系統概念篇
- Android系統開發小記:FingerprintManagerAndroid