一、引言
Android系統非常龐大、錯綜複雜,其底層是採用Linux作爲基底,上層採用包含虛擬機的Java層以及Native層,通過系統調用(Syscall)連通系統的內核空間與用戶空間。用戶空間主要採用C++和Java代碼,通過JNI技術打通用戶空間的Java層和Native層(C++/C),從而融爲一體。
Google官方提供了一張經典的四層架構圖,從下往上依次分爲Linux內核、系統庫和Android運行時環境、框架層以及應用層這4層架構,其中每一層都包含大量的子模塊或子系統。這只是如壘磚般地分層,並沒有表達Android整個系統的內部架構、運行機理,以及各個模塊之間是如何銜接與配合工作的。爲了更深入地掌握Android整個架構思想以及各個模塊在Android系統所處的地位與價值,計劃以Android系統啓動過程爲主線,以進程的視角來詮釋Android M系統全貌,全方位的深度剖析各個模塊功能,爭取各個擊破。這樣才能猶如庖丁解牛,解決、分析問題則能遊刃有餘。
二、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用於管理系統中的各種服務。
- 想進一步瞭解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的startThreadPool過程 |
7 | 徹底理解Android Binder通信架構 | startService爲主線 |
8 | Binder系列10—總結 | Binder的簡單總結 |
9 | Binder IPC的權限控制 | clearCallingIdentity/restoreCallingIdentity |
10 | Binder死亡通知機制之linkToDeath | Binder死亡通知機制 |
驅動篇:
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實例對象mHandler
位於線程間共享的內存堆上,工作線程與主線程都能直接使用該對象,只需要注意多線程的同步問題。工作線程通過mHandler
向其成員變量MessageQueue
中添加新Message,主線程一直處於loop()方法內,當收到新的Message時按照一定規則分發給相應的handleMessage
()方法來處理。所以說,而Handler消息機制用於同進程的線程間通信的核心是線程間共享內存空間,而不同進程擁有不同的地址空間,也就不能用handler來實現進程間通信。
上圖只是Handler消息機制的一種處理流程,是不是隻能工作線程向UI主線程發消息呢,其實不然,可以是UI線程向工作線程發送消息,也可以是多個工作線程之間通過handler發送消息。更多關於Handler消息機制文章:
要理解framework層源碼,掌握這3種基本的進程/線程間通信方式是非常有必要,當然Linux還有不少其他的IPC機制,比如共享內存、信號、信號量,在源碼中也有體現,如果想全面徹底地掌握Android系統,還是需要對每一種IPCd機制都有所瞭解。
四、核心提綱
2016年新的一年剛開始,首先祝大家、也祝自己在新的一年諸事順心,事業蒸蒸日上。在過去的一年,對於Android從底層一路到上層有不少自己的理解和沉澱,但總體較零散,未成體系。藉着今天(元旦假日的最後一天),給自己的新的一年提前做一個計劃,把知識進行歸檔整理與再學習,從而加深對Android架構的理解。通過前面對系統啓動的介紹,相信大家對Android系統有了一個整體觀,接下來需要抓核心、理思路,爭取各個擊破。
計劃:不少文章還沒來得及進一步加工,大篇章的源碼,有讀者跟我反饋看着發睏,先別急,文章還會不斷更新和升級。前期計劃先將系統所有核心技術點的邊整理邊寫博客; 後期工作有時間再根據大家的反饋以及自己的校驗,再不斷修正和完善所有文章,爭取給文章,再進一步精簡非核心代碼,增加可視化圖表以及文字的結論性分析。
博客定位: 基於Android 6.0的源碼
,專注於分享Android系統原理、架構分析的原創文章。
建議閱讀羣體: 適合於正從事或者有興趣研究Android系統的工程師或者愛好者,也適合Android app高級工程師; 對於尚未入門或者剛入門的app程序員閱讀可能會困難些,可能不是很適合。
看到Android整個系統架構是如此龐大的, 該問如何學習Android系統, 以下是我自己琢磨的Android的學習和研究論,僅供參考:如何自學Android.
4.1 系統啓動系列
Android系統啓動-概述: Android系統中極其重要進程:init, zygote, system_server, servicemanager 進程:
序號 | 進程啓動 | 概述 |
1 | init進程 | Linux系統中用戶空間的第一個進程, Init.main |
2 | zygote進程 | 所有App進程的父進程, ZygoteInit.main |
3 | system_server進程(上篇) | 系統各大服務的載體, forkSystemServer過程 |
4 | system_server進程(下篇) | 系統各大服務的載體, SystemServer.main |
5 | servicemanager進程 | binder服務的大管家, 守護進程循環運行在binder_loop |
6 | app進程 | 通過Process.start啓動App進程, ActivityThread.main |
再來看看守護進程(進程名一般以d爲後綴,比如logd), 先介紹以下部分,後綴再增加.
4.2 系統穩定性系列
Android系穩定性主要是異常崩潰(crash)和執行超時(timeout), Android系統穩定性簡述 :
序號 | 文章名 | 概述 |
1 | 理解Android ANR的觸發原理 | 觸發ANR的場景以及機理 |
2 | Input系統—ANR原理分析 | input觸發ANR的原理 |
3 | 理解Android ANR的信息收集過程 | AMS.appNotResponding過程分析,收集traces |
4 | ART虛擬機之Trace原理 | kill -3 信息收集過程 |
5 | Native進程之Trace原理 | debuggerd -b 信息收集過程 |
6 | WatchDog工作原理 | WatchDog觸發機制 |
7 | 理解Java Crash處理流程 | AMS.handleApplicationCrash過程分析 |
8 | 理解Native Crash處理流程 | debuggerd守護進程 |
4.3 Android進程系列
進程對於系統非常重要,系統運轉,各種服務、組件的載體都依託於進程,對進程理解越深刻,越能掌握系統整體架構。那麼先來看看進程相關:
序號 | 文章名 | 概述 |
1 | 理解Android進程創建流程 | Process.start過程分析 |
2 | 理解殺進程的實現原理 | Process.killProcess過程分析 |
3 | Android四大組件與進程啓動的關係 | AMS.startProcessLocked過程分析組件與進程 |
4 | Android進程絕殺技–forceStop | force-stop過程分析徹底移除組件與殺進程 |
5 | 理解Android線程創建流程 | 3種不同線程的創建過程 |
6 | 徹底理解Android Binder通信架構 | 以start-service爲線,闡述進程間通信機理 |
7 | 理解Binder線程池的管理 | Zygote fork的進程都默認開啓binder線程池 |
8 | Android進程生命週期與ADJ | 進程adj, processState以及lmk |
9 | Android LowMemoryKiller原理分析 | lmk原理分析 |
10 | 進程優先級 | 進程nice,thread priority以及scheduler |
11 | Android進程調度之adj算法 | updateOomAdjLocked過程 |
12 | Android進程整理 | 整理系統的所有進程/線程 |
4.4 四大組件系列
對於App來說,Android應用的四大組件Activity,Service,Broadcast Receiver, Content Provider最爲核心,接下分別展開介紹:
序號 | 文章名 | 類別 |
1 | startActivity啓動過程分析 | Activity |
2 | 簡述Activity生命週期 | Activity |
3 | startService啓動過程分析 | Service |
4 | bindService啓動過程分析 | Service |
5 | 以Binder視角來看Service啓動 | Service |
6 | Android Broadcast廣播機制分析 | Broadcast |
7 | 理解ContentProvider原理 | ContentProvider |
8 | ContentProvider引用計數 | ContentProvider |
9 | Activity與Service生命週期 | Activity&&Service |
10 | 簡述Activity與Window關係 | Activity&&Window |
11 | 四大組件之綜述 | AMS |
12 | 四大組件之ServiceRecord | Service |
13 | 四大組件之BroadcastRecord | Broadcast |
14 | 四大組件之ContentProviderRecord | ContentProvider |
15 | 理解Android Context | Context |
16 | 理解Application創建過程 | Application |
17 | unbindService流程分析 | Service |
18 | 四大組件之ActivityRecord | Activity |
19 | AMS總結(一) | AMS |
4.5 圖形系統系列
圖形也是整個系統非常複雜且重要的一個系列,涉及WindowManager,SurfaceFlinger.
序號 | 文章名 | 類別 |
1 | WindowManager啓動篇 | Window |
2 | WMS之啓動窗口篇 | Window |
3 | 以Window視角來看startActivity | Window |
4 | Android圖形系統概述 | SurfaceFlinger |
5 | SurfaceFlinger啓動篇 | SurfaceFlinger |
6 | SurfaceFlinger繪圖篇 | SurfaceFlinger |
7 | Choreographer原理 | Choreographer |
4.6 系統服務篇
再則就是在整個架構中有大量的服務,都是基於Binder來交互的,計劃針對部分核心服務來重點分析:
系統服務的註冊過程, 見Android系統服務的註冊方式
- AMS服務
- AMS啓動過程(一)
- 更多組件篇[見小節4.3]
- Input系統
- PKMS服務
- Alarm服務
- JobScheduler服務
- BatteryService
- PMS服務
- DropBox服務
- UserManagerService
- 更多服務介紹, 敬請期待…
4.7 內存&&存儲篇
- 內存篇
- 存儲篇
- Linux驅動篇
- 敬請期待
- dalvik/art
4.8 工具篇
最後,說說Android相關的一些常用命令和工具以及調試手段.
序號 | 文章名 | 類別 |
1 | 理解Android編譯命令 | build |
2 | 性能工具Systrace | systrace |
3 | Android內存分析命令 | Memory |
4 | ps進程命令 | Process |
5 | Am命令用法 | Am |
6 | Pm命令用法 | Pm |
7 | 調試系列1:bugreport源碼篇 | bugreport |
8 | 調試系列2:bugreport實戰篇 | bugreport |
9 | dumpsys命令用法 | dumpsys |
五、結束語
計劃: 後續持續新增和完善整個大綱,不限於進程、內存、IO、系統服務框架,整體架構以及各種系統分析實戰等文章。 博客會持續更新,各個擊破,本文最近更新時間點: 2017.09.03
.
以上內容轉自:gityuan的Android系統開篇