Android架構(gòu)層次

1 引言

本文作為Android系統(tǒng)架構(gòu)的開篇,起到提綱挈領(lǐng)的作用,從系統(tǒng)整體架構(gòu)角度概要講解Android系統(tǒng)的核心技術(shù)點,帶領(lǐng)大家初探Android系統(tǒng)全貌以及內(nèi)部運作機制。雖然Android系統(tǒng)非常龐大且錯綜復(fù)雜,需要具備全面的技術(shù)棧,但整體架構(gòu)設(shè)計清晰。Android底層內(nèi)核空間以Linux Kernel作為基石,上層用戶空間由Native系統(tǒng)庫、虛擬機運行環(huán)境、框架層組成,通過系統(tǒng)調(diào)用(Syscall)連通系統(tǒng)的內(nèi)核空間與用戶空間。對于用戶空間主要采用C++和Java代碼編寫,通過JNI技術(shù)打通用戶空間的Java層和Native層(C++/C),從而連通整個系統(tǒng)。

為了能讓大家整體上大致了解Android系統(tǒng)涉及的知識層面,先來看一張Google官方提供的經(jīng)典分層架構(gòu)圖,從下往上依次分為Linux內(nèi)核、HAL、系統(tǒng)Native庫和Android運行時環(huán)境、Java框架層以及應(yīng)用層這5層架構(gòu),其中每一層都包含大量的子模塊或子系統(tǒng)。


Android框架層次.jpeg

上圖采用靜態(tài)分層方式的架構(gòu)劃分,眾所周知,程序代碼是死的,系統(tǒng)運轉(zhuǎn)是活的,各模塊代碼運行在不同的進程(線程)中,相互之間進行著各種錯終復(fù)雜的信息傳遞與交互流,從這個角度來說此圖并沒能體現(xiàn)Android整個系統(tǒng)的內(nèi)部架構(gòu)、運行機理,以及各個模塊之間是如何銜接與配合工作的。

1.1 Linux內(nèi)核層

Android以Linux操作系統(tǒng)內(nèi)核為基礎(chǔ),借助Linux內(nèi)核服務(wù)實現(xiàn)硬件設(shè)備驅(qū)動,進程和內(nèi)存管理,網(wǎng)絡(luò)協(xié)議棧,電源管理,無線通信、設(shè)備驅(qū)動、文件系統(tǒng)、Binder (IPC) 驅(qū)動等核心功能。Android4.0版本之前基于Linux2.6系列內(nèi)核,4.0及之后的版本使用更新的Linux3.X內(nèi)核,并且兩個開源項目開始有了互通。Linux3.3內(nèi)核中正式包括一些Android代碼,可以直接引導(dǎo)進入Android。Linux3.4將會增添電源管理等更多功能,以增加與Android的硬件兼容性,使Android在更多設(shè)備上得到支持。

Android內(nèi)核 對Linux內(nèi)核進行了增強,增加了一些面向移動計算的特有功能。例如,低內(nèi)存管理器LMK(Low Memory Keller),匿名共享內(nèi)存(Ashmem),以及輕量級的進程間通信Binder機制等。這些內(nèi)核的增強使Android在繼承Linux內(nèi)核安全機制的同時,進一步提升了內(nèi)存管理,進程間通信等方面的安全性。下表列舉了Android內(nèi)核的主要驅(qū)動模塊:

驅(qū)動名稱 說明
電源管理(Power Manager) 針對嵌入式設(shè)備,基于標準Linux電源管理系統(tǒng),輕量級的電源管理驅(qū)動
低內(nèi)存管理器(Low Memory Killer) 拓展了Linux的OOM機制,形成獨特的LMK機制
匿名共享內(nèi)存(Ashmem) 為進程之間提供共享內(nèi)存資源,同時為內(nèi)核提供回收和管理內(nèi)存的機制
日志(Android Logger) 輕量級的日志設(shè)備
定時器(Android Alarm) 用于把設(shè)備從睡眠狀態(tài)喚醒
物理內(nèi)存映射管理(Android PMEM) DSP以及其他設(shè)備只能工作在連續(xù)的物理內(nèi)存上,PMEM用于向用戶空間提供連續(xù)的物理內(nèi)存區(qū)域映射
Yaffs2文件系統(tǒng) Android采用大容量的NADN閃存作為儲存設(shè)備,使用Yaffs2 作為文件系統(tǒng)管理大容量MTD NAND Flash;Yaffs2占用內(nèi)存小,垃圾回收簡潔迅速。
定時設(shè)備(Android Timed device) 可以執(zhí)行對設(shè)備的定時控制功能
Paranoid網(wǎng)絡(luò) 對Linux內(nèi)核的網(wǎng)絡(luò)代碼進行了改動,增加了網(wǎng)絡(luò)認證機制。可在IPV4、IVP6和藍牙中設(shè)置,由ANDROID_PARANOID_NETWORK宏來啟用此特性。

1.2 HAL-硬件抽象層

許多硬件設(shè)備廠商不希望公開其設(shè)備驅(qū)動的源代碼,如果能將android的應(yīng)用框架層與linux系統(tǒng)內(nèi)核的設(shè)備驅(qū)動隔離,使應(yīng)用程序框架的開發(fā)盡量獨立于具體的驅(qū)動程序,則android將減少對Linux內(nèi)核的依賴,HAL由此而生。

HAL(Hardware Abstract Layer硬件抽象層)是Google因應(yīng)廠商「希望不公開源碼」的要求下,所推出的新觀念。它對Linux內(nèi)核驅(qū)動程序進行封裝,將硬件抽象化,屏蔽掉底層的實現(xiàn)細節(jié)。規(guī)定了一套應(yīng)用層對硬件層讀寫和配置的統(tǒng)一接口,本質(zhì)上就是將硬件的驅(qū)動分為用戶空間和內(nèi)核空間兩個層面,Linux內(nèi)核驅(qū)動程序運行于內(nèi)核空間,硬件抽象層運行于用戶空間。HAL設(shè)備驅(qū)動抽象使得應(yīng)用程序和驅(qū)動程序之間很明顯地區(qū)分開來。 驅(qū)動抽象促進了應(yīng)用程序代碼的可重用性,應(yīng)用程序和底層硬件的通信依靠統(tǒng)一的接口函數(shù),底層硬件的改動對應(yīng)用程序的代碼沒有影響。而且,HAL標準使得和已有外設(shè)相匹配的新外設(shè)的驅(qū)動程序編寫起來更加簡單。

1.3 Android Runtime

  • Java核心庫
    核心庫提供了Java5 se API的多數(shù)功能,并提供Android的核心API,如android.os,android.net,android.media等。該核心庫提供了JAVA編程語言核心庫的大多數(shù)功能。

  • Dalvik VM(5.0之前)
    Dalvik VM在2010年5月21日,Google公司發(fā)布的Android2.2版本中正式使用,一直沿用到Android5.0版本。借助新的Dalvik JIT編譯器(Just In Time,即時編譯器),CPU密集型應(yīng)用的速度比Android2.1快2-5倍,Android2.2還改進了App可以安裝在SD卡(外部存儲)上。
    Dalvik VM前身基于apache的java虛擬機,并被改進以適應(yīng)低內(nèi)存,低處理器速度的移動設(shè)備環(huán)境。Dalvik VM基于寄存器,使用.dex可執(zhí)行文件,依賴于Linux內(nèi)核,實現(xiàn)進程隔離與線程調(diào)試管理,安全和異常管理,垃圾回收等重要功能。

  • ART VM(5.0正式啟用)
    Dalvik虛擬機從DEX(Dalvik Executable)格式的文件中讀取指令與數(shù)據(jù),進行解釋運行,JIT 在運行時將字節(jié)碼翻譯為本地機器指令,運行一次就要編譯一次,性能還是很低。于是Android4.4版本支持了ART模式,并在Android5.0正式將編譯模式由ART取代Dalvik VM成為默認選項。
    ART 采用預(yù)編譯AOT(ahead-of-time)技術(shù),在應(yīng)用程序安裝時,將程序代碼一次性轉(zhuǎn)化為機器語言,省去了程序在運行時每次編譯的時間,加快了程序運行速度,使得電量消耗更少,系統(tǒng)更加流暢。

1.4 Native C/C++ Libraries

系統(tǒng)類庫大部分由C/C++編寫,所提供的功能通過Android應(yīng)用程序框架為開發(fā)者所使用,如資源文件管理、基礎(chǔ)算法庫。第三方類庫,極大的加快了Android應(yīng)用的開發(fā)周期。

主要的第三方類庫及說明如下表:

庫名稱 說明
Webkit Web瀏覽器的軟件引擎
OpenMAX AL 多媒體應(yīng)用程序的框架標準,由NVIDIA公司和Khronos在2006年推出
Libc 繼承自BSD的c函數(shù)庫bionic libc,更適合基于嵌入式Linux的移動設(shè)備
Media Framework 基于Packet Video Open Core的多媒體庫,支持多種常用的音頻和視頻格式的錄制和回放,所支持的編碼格式包括MPEG4,MP3,H264,AAC,ARM
OpenGL ES 基于OpenGL ES1.0 API標準實現(xiàn)的3D跨平臺圖形庫
Surface Manager 執(zhí)行多個應(yīng)用程序時,管理子系統(tǒng)的顯示,另外對2D和3D圖形提供支持;
SQLite 本地小型關(guān)系數(shù)據(jù)庫,android提供了一些新的SQLite數(shù)據(jù)庫API,以替代傳統(tǒng)的耗費資源的JDBC API
FreeType 用于顯示位圖和矢量字體
SGL 底層的2D圖形引擎
SSL 安全套接層,為網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議

除上表列舉的主要系統(tǒng)類庫之外,Android NDK(Native Development Kit),即Android原生庫,也十分重要。NDK為開發(fā)者提供了直接使用Android系統(tǒng)資源,并采用C或C++語言編寫程序的接口。因此,第三方應(yīng)用程序可以不依賴于Dalvik虛擬機進行開發(fā)。實際上,NDK提供了一系列從C或C++生成原生代碼所需要的工具,為開發(fā)者快速開發(fā)C或C++的動態(tài)庫提供方便,并能自動將生成的動態(tài)庫和java應(yīng)用程序一起打包成應(yīng)用程序包文件。

1.5 Application Framework(應(yīng)用框架層)

應(yīng)用框架層提供了一些類的類庫框架,方便開發(fā)人員調(diào)用,通過組件重用能夠快速開發(fā)出應(yīng)用程序。具體模塊如下表所示:

管理器/組件 功能
Content Provider(內(nèi)容提供器) 提供一個應(yīng)用程序訪問另一個應(yīng)用程序數(shù)據(jù)的功能,或者實現(xiàn)應(yīng)用程序之間的數(shù)據(jù)共享
View System(視圖系統(tǒng)) 提供各種視圖控件,如列表、網(wǎng)格、文本框、按鈕、可嵌套的web瀏覽器
Activity Manager(活動管理器) 管理各種應(yīng)用程序生命周期,為所有程序的窗口提供交互的接口
Location Manager(位置管理器) 提供位置服務(wù)
Package Manager(包管理器) 對應(yīng)用程序進行管理,如安裝應(yīng)用程序、卸載應(yīng)用程序、查詢相關(guān)權(quán)限等
Notification Manager(通知管理器) 使應(yīng)用程序可以在狀態(tài)欄中顯示自定義的提示信息
Resource Manager(資源管理器) 提供各種非代碼資源供應(yīng)用程序使用,如本地化字符串、圖片、音頻等
Telephony Manager(電話管理器) 提供電話相關(guān)信息的查詢/修改功能,以及狀態(tài)監(jiān)聽功能
Window Mangaer(窗口管理器) 對開啟的窗口進行管理

1.6 Apps

該層提供一些核心應(yīng)用程序包,例如電子郵件、短信、日歷、地圖、瀏覽器和聯(lián)系人管理等。同時,開發(fā)者可以利用Java語言設(shè)計和編寫屬于自己的應(yīng)用程序,而這些程序與那些核心應(yīng)用程序彼此獨立。

為了更深入地掌握Android整個架構(gòu)思想以及各個模塊在Android系統(tǒng)所處的地位與價值,計劃以Android系統(tǒng)啟動過程為主線,以進程的視角來詮釋Android M系統(tǒng)全貌,全方位的深度剖析各個模塊功能,爭取各個擊破。這樣才能猶如庖丁解牛,解決、分析問題則能游刃有余。

2 Android架構(gòu)

Google提供的5層架構(gòu)圖很經(jīng)典,但為了更進一步透視Android系統(tǒng)架構(gòu),本文更多的是以進程的視角,以分層的架構(gòu)來詮釋Android系統(tǒng)的全貌,闡述Android內(nèi)部的環(huán)環(huán)相扣的內(nèi)在聯(lián)系。
系統(tǒng)啟動架構(gòu)圖

系統(tǒng)啟動架構(gòu)圖.jpeg

圖解:Android系統(tǒng)啟動過程由上圖從下往上的一個過程是由Boot Loader引導(dǎo)開機,然后依次進入 -> Kernel -> Native -> Framework -> App,接來下簡要說說每個過程:

關(guān)于Loader層:

  • Boot ROM: 當(dāng)手機處于關(guān)機狀態(tài)時,長按Power鍵開機,引導(dǎo)芯片開始從固化在 ROM里的預(yù)設(shè)代碼開始執(zhí)行,然后加載引導(dǎo)程序到 RAM;
  • Boot Loader:這是啟動Android系統(tǒng)之前的引導(dǎo)程序,主要是檢查RAM,初始化硬件參數(shù)等功能。

2.1 Linux內(nèi)核層

Android平臺的基礎(chǔ)是Linux內(nèi)核,比如ART虛擬機最終調(diào)用底層Linux內(nèi)核來執(zhí)行功能。Linux內(nèi)核的安全機制為Android提供相應(yīng)的保障,也允許設(shè)備制造商為內(nèi)核開發(fā)硬件驅(qū)動程序。

  • 啟動Kernel的swapper進程(pid=0):該進程又稱為idle進程, 系統(tǒng)初始化過程Kernel由無到有開創(chuàng)的第一個進程, 用于初始化進程管理、內(nèi)存管理,加載Display,Camera Driver,Binder Driver等相關(guān)工作;
  • 啟動kthreadd進程(pid=2):是Linux系統(tǒng)的內(nèi)核進程,會創(chuàng)建內(nèi)核工作線程kworkder,軟中斷線程ksoftirqd,thermal等內(nèi)核守護進程。 kthreadd進程是所有內(nèi)核進程的鼻祖。

2.2 硬件抽象層 (HAL)

硬件抽象層 (HAL) 提供標準接口,HAL包含多個庫模塊,其中每個模塊都為特定類型的硬件組件實現(xiàn)一組接口,比如WIFI/藍牙模塊,當(dāng)框架API請求訪問設(shè)備硬件時,Android系統(tǒng)將為該硬件加載相應(yīng)的庫模塊。

2.3 Android Runtime & 系統(tǒng)庫

每個應(yīng)用都在其自己的進程中運行,都有自己的虛擬機實例。ART通過執(zhí)行DEX文件可在設(shè)備運行多個虛擬機,DEX文件是一種專為Android設(shè)計的字節(jié)碼格式文件,經(jīng)過優(yōu)化,使用內(nèi)存很少。ART主要功能包括:預(yù)先(AOT)和即時(JIT)編譯,優(yōu)化的垃圾回收(GC),以及調(diào)試相關(guān)的支持。

這里的Native系統(tǒng)庫主要包括init孵化來的用戶空間的守護進程、HAL層以及開機動畫等。啟動init進程(pid=1),是Linux系統(tǒng)的用戶進程, init進程是所有用戶進程的鼻祖。

  • init進程會孵化出ueventd、logd、healthd、installd、adbd、lmkd等用戶守護進程;
  • init進程還啟動 servicemanager(binder服務(wù)管家)、 bootanim(開機動畫)等重要服務(wù);
  • init進程孵化出Zygote進程,Zygote進程是Android系統(tǒng)的第一個Java進程(即虛擬機進程),** Zygote是所有Java進程的父進程**,Zygote進程本身是由init進程孵化而來的。

2.4 Framework層

Zygote進程,是由init進程通過解析init.rc文件后fork生成的,Zygote進程主要包含:

  • 加載ZygoteInit類,注冊Zygote Socket服務(wù)端套接字
  • 加載虛擬機
  • 提前加載類preloadClasses
  • 提前加載資源preloadResouces
  • System Server進程,是由Zygote進程fork而來,** SystemServer是Zygote孵化的第一個進程**,System Server負責(zé)啟動和管理整個Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服務(wù)。
  • Media Server進程,是由init進程fork而來,負責(zé)啟動和管理整個C++ framework,包含AudioFlinger,Camera Service等服務(wù)。

2.5 App層

  • Zygote進程孵化出的第一個App進程是Launcher,這是用戶看到的桌面App;
  • Zygote進程還會創(chuàng)建Browser,Phone,Email等App進程,每個App至少運行在一個進程上。
  • 所有的App進程都是由Zygote進程fork生成的。

2.6 Syscall && JNI

  • Native與Kernel之間有一層系統(tǒng)調(diào)用(SysCall)層,見Linux系統(tǒng)調(diào)用(Syscall)原理;
  • Java層與Native(C/C++)層之間的紐帶JNI,見Android JNI原理分析。

3 通信方式

無論是Android系統(tǒng),還是各種Linux衍生系統(tǒng),各個組件、模塊往往運行在各種不同的進程和線程內(nèi),這里就必然涉及進程/線程之間的通信。對于IPC(Inter-Process Communication, 進程間通信),Linux現(xiàn)有管道、消息隊列、共享內(nèi)存、套接字、信號量、信號這些IPC機制,Android額外還有Binder IPC機制。Android OS中的Zygote進程的IPC采用的是Socket機制,在上層system server、media server以及上層App之間更多的是采用Binder IPC方式來完成跨進程間的通信。對于Android上層架構(gòu)中,很多時候是在同一個進程的線程之間需要相互通信,例如同一個進程的主線程與工作線程之間的通信,往往采用的Handler消息機制。

想深入理解Android內(nèi)核層架構(gòu),必須先深入理解Linux現(xiàn)有的IPC機制;對于Android上層架構(gòu),則最常用的通信方式是Binder、Socket、Handler,當(dāng)然也有少量其他的IPC方式,比如殺進程Process.killProcess()采用的是signal方式。下面說說Binder、Socket、Handler:

3.1 Binder

Binder作為Android系統(tǒng)提供的一種IPC機制,無論從系統(tǒng)開發(fā)還是應(yīng)用開發(fā),都是Android系統(tǒng)中最重要的組成,也是最難理解的一塊知識點。深入了解Binder機制,最好的方法便是閱讀源碼,借用Linux鼻祖Linus Torvalds曾說過的一句話:Read The Fucking Source Code。下面簡要說說Binder IPC原理。

Binder通信采用c/s架構(gòu),從組件視角來說,包含Client、Server、ServiceManager以及binder驅(qū)動,其中ServiceManager用于管理系統(tǒng)中的各種服務(wù)。


Binder IPC原理.jpeg

想進一步了解Binder,可查看Binder系列—開篇,Binder系列花費了13篇文章的篇幅,從源碼角度出發(fā)來講述Driver、Native、Framework、App四個層面的整個完整流程。根據(jù)有些讀者反饋這個系列還是不好理解,這個binder涉及的層次跨度比較大,知識量比較廣,建議大家先知道binder是用于進程間通信,有個大致概念就可以先去學(xué)習(xí)系統(tǒng)基本知識,等后面有一定功力再進一步深入研究Binder機制。

3.2 Socket

Socket通信方式也是C/S架構(gòu),比Binder簡單很多。在Android系統(tǒng)中采用Socket通信方式的主要有:

  • zygote:用于孵化進程,system_server創(chuàng)建進程是通過socket向zygote進程發(fā)起請求;
  • installd:用于安裝App的守護進程,上層PackageManagerService很多實現(xiàn)最終都是交給它來完成;
  • lmkd:lowmemorykiller的守護進程,Java層的LowMemoryKiller最終都是由lmkd來完成;
  • adbd:這個不用說,用于服務(wù)adb;
  • logcatd:這個不用說,用于服務(wù)logcat;
  • vold:即volume Daemon,是存儲類的守護進程,用于負責(zé)如USB、Sdcard等存儲設(shè)備的事件處理。
    等等還有很多,這里不一一列舉,Socket方式更多的用于Android framework層與native層之間的通信。Socket通信方式相對于binder比較簡單,這里省略。

3.3 Handler

Binder/Socket用于進程間通信,而Handler消息機制用于同進程的線程間通信,Handler消息機制是由一組MessageQueue、Message、Looper、Handler共同組成的,為了方便且稱之為Handler消息機制。

有人可能會疑惑,為何Binder/Socket用于進程間通信,能否用于線程間通信呢?答案是肯定,對于兩個具有獨立地址空間的進程通信都可以,當(dāng)然也能用于共享內(nèi)存空間的兩個線程間通信,這就好比殺雞用牛刀。接著可能還有人會疑惑,那handler消息機制能否用于進程間通信?答案是不能,Handler只能用于共享內(nèi)存地址空間的兩個線程間通信,即同進程的兩個線程間通信。很多時候,Handler是工作線程向UI主線程發(fā)送消息,即App應(yīng)用中只有主線程能更新UI,其他工作線程往往是完成相應(yīng)工作后,通過Handler告知主線程需要做出相應(yīng)地UI更新操作,Handler分發(fā)相應(yīng)的消息給UI主線程去完成,如下圖:


Handler通信.jpeg

由于工作線程與主線程共享地址空間,即Handler實例對象mHandler位于線程間共享的內(nèi)存堆上,工作線程與主線程都能直接使用該對象,只需要注意多線程的同步問題。工作線程通過mHandler向其成員變量MessageQueue中添加新Message,主線程一直處于loop()方法內(nèi),當(dāng)收到新的Message時按照一定規(guī)則分發(fā)給相應(yīng)的handleMessage()方法來處理。所以說,Handler消息機制用于同進程的線程間通信,其核心是線程間共享內(nèi)存空間,而不同進程擁有不同的地址空間,也就不能用handler來實現(xiàn)進程間通信。

上圖只是Handler消息機制的一種處理流程,是不是只能工作線程向UI主線程發(fā)消息呢,其實不然,可以是UI線程向工作線程發(fā)送消息,也可以是多個工作線程之間通過handler發(fā)送消息。

參考資料:

[1] Android系統(tǒng)架構(gòu)開篇 ★★★
[2] 從Android架構(gòu)圖看開發(fā)所需的知識點
[3] Android系統(tǒng)架構(gòu)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容