當前位置:
首頁 > 知識 > 掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

Android系統龐大且錯綜複雜,本文作者Gityuan將帶領大家初探Android系統整體架構,一窺其全貌。

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

打開今日頭條,查看更多圖片

作者 | 袁輝輝

本文經授權轉載自Android達摩院(ID:gityuanblog)

引言

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

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

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

上圖採用靜態分層方式的架構劃分,眾所周知,程序代碼是死的,系統運轉是活的,各模塊代碼運行在不同的進程(線程)中,相互之間進行著各種錯終複雜的信息傳遞與交互流,從這個角度來說此圖並沒能體現Android整個系統的內部架構、運行機理,以及各個模塊之間是如何銜接與配合工作的。為了更深入地掌握Android整個架構思想以及各個模塊在Android系統所處的地位與價值,計劃以Android系統啟動過程為主線,以進程的視角來詮釋Android M系統全貌,全方位的深度剖析各個模塊功能,爭取各個擊破。這樣才能猶如庖丁解牛,解決、分析問題則能遊刃有餘。

Android架構

Google提供的5層架構圖很經典,但為了更進一步透視Android系統架構,本文更多的是以進程的視角,以分層的架構來詮釋Android系統的全貌,闡述Android內部的環環相扣的內在聯繫。

系統啟動架構圖

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

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

關於Loader層:

  • Boot ROM: 當手機處於關機狀態時,長按Power鍵開機,引導晶元開始從固化在 ROM里的預設代碼開始執行,然後載入引導程序到 RAM;
  • Boot Loader:這是啟動Android系統之前的引導程序,主要是檢查RAM,初始化硬體參數等功能。

2.1 Linux內核層

Android平台的基礎是Linux內核,比如ART虛擬機最終調用底層Linux內核來執行功能。Linux內核的安全機製為Android提供相應的保障,也允許設備製造商為內核開發硬體驅動程序。

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

2.2 硬體抽象層 (HAL)

硬體抽象層 (HAL) 提供標準介面,HAL包含多個庫模塊,其中每個模塊都為特定類型的硬體組件實現一組介面,比如WIFI/藍牙模塊,當框架API請求訪問設備硬體時,Android系統將為該硬體載入相應的庫模塊。

2.3 Android Runtime & 系統庫

每個應用都在其自己的進程中運行,都有自己的虛擬機實例。ART通過執行DEX文件可在設備運行多個虛擬機,DEX文件是一種專為Android設計的位元組碼格式文件,經過優化,使用內存很少。ART主要功能包括:預先(AOT)和即時(JIT)編譯,優化的垃圾回收(GC),以及調試相關的支持。

這裡的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而來, SystemServer是Zygote孵化的第一個進程,System Server負責啟動和管理整個Java framework,包含ActivityManager,WindowManager,PackageManager,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機制? 可查看我在知乎上的回答(https://www.zhihu.com/question/39440766/answer/89210950)。深入了解Binder機制,最好的方法便是閱讀源碼,借用Linux鼻祖Linus Torvalds曾說過的一句話:Read The Fucking Source Code。下面簡要說說Binder IPC原理。

Binder IPC原理

Binder通信採用c/s架構,從組件視角來說,包含Client、Server、ServiceManager以及binder驅動,其中ServiceManager用於管理系統中的各種服務。

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

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

Binder原理篇(具體文章地址可詳見:http://gityuan.com/android/)

序號文章名概述0Binder系列—開篇Binder概述1Binder系列3—啟動Service ManagerServiceManager守護進程 註冊和查詢服務2Binder系列4—獲取Service Manager獲取代理對象BpServiceManager3Binder系列5—註冊服務(addService)註冊Media服務4Binder系列6—獲取服務(getService)獲取Media代理,以及DeathRecipient5Binder系列7—framework層分析framework層服務註冊和查詢,Binder註冊6理解Binder線程池的管理Binder的startThreadPool過程7徹底理解Android Binder通信架構startService為主線8Binder系列10—總結Binder的簡單總結9Binder IPC的許可權控制clearCallingIdentity/restoreCallingIdentity10Binder死亡通知機制之linkToDeathBinder死亡通知機制

Binder驅動篇:

1Binder Driver初探驅動open/mmap/ioctl,以及binder結構體2Binder Driver再探Binder通信協議,內存機制

Binder使用篇:

1如何使用BinderNative層、Framwrok層自定義Binder服務2如何使用AIDLApp層自定義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主線程去完成,如下圖:

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

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

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

  • Android消息機制-Handler(framework篇)(http://gityuan.com/2015/12/26/handler-message-framework/)
  • Android消息機制-Handler(native篇)(http://gityuan.com/2015/12/27/handler-message-native/)
  • Android消息機制3-Handler(實戰)(http://gityuan.com/2016/01/01/handler-message-usage/)

要理解framework層源碼,掌握這3種基本的進程/線程間通信方式是非常有必要,當然Linux還有不少其他的IPC機制,比如共享內存、信號、信號量,在源碼中也有體現,如果想全面徹底地掌握Android系統,還是需要對每一種IPC機制都有所了解。

核心提綱

博主對於Android從系統底層一路到上層都有自己的理解和沉澱,通過前面對系統啟動的介紹,相信大家對Android系統有了一個整體觀。接下來需抓核心、理思路,爭取各個擊破。後續將持續更新和完善整個大綱,不限於進程、內存、IO、系統服務架構以及分析實戰等文章。

當然本站有一些文章沒來得及進一步加工,有時間根據大家的反饋,不斷修正和完善所有文章,爭取給文章,再進一步精簡非核心代碼,增加可視化圖表以及文字的結論性分析。基於Android 6.0的源碼,專註於分享Android系統原理、架構分析的原創文章。

建議閱讀群體: 適合於正從事或者有興趣研究Android系統的工程師或者技術愛好者,也適合Android App高級工程師;對於尚未入門或者剛入門的App工程師閱讀可能會有點困難,建議先閱讀更基礎的資料,再來閱讀本站博客。

看到Android整個系統架構是如此龐大的, 該問如何學習Android系統, 以下是我自己的Android的學習和研究論,僅供參考如何自學Android(http://gityuan.com/2016/04/24/how-to-study-android/)。

從整理上來列舉一下Android系統的核心知識點概覽:

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

4.1 系統啟動系列

掌握 Android 系統架構,看這一篇就夠了!| 技術頭條

Android系統啟動-概述:

鏈接地址:http://gityuan.com/2016/02/01/android-booting/

Android系統中極其重要進程:init, zygote, system_server, servicemanager 進程:

序號進程啟動概述1init進程Linux系統中用戶空間的第一個進程, Init.main2zygote進程所有App進程的父進程, ZygoteInit.main3system_server進程(上篇)系統各大服務的載體, forkSystemServer過程4system_server進程(下篇)系統各大服務的載體, SystemServer.main5servicemanager進程binder服務的大管家, 守護進程循環運行在binder_loop6App進程通過Process.start啟動App進程, ActivityThread.main

再來看看守護進程(也就是進程名一般以d為後綴,比如logd,此處d是指daemon的簡稱), 下面介紹部分守護進程:

  • debuggerd
  • installd
  • lmkd
  • logd

4.2 系統穩定性系列

Android系統穩定性主要是異常崩潰(crash)和執行超時(timeout):

鏈接地址:http://gityuan.com/2016/06/19/stability_summary/

序號文章名概述1理解Android ANR的觸發原理觸發ANR的場景以及機理2Input系統—ANR原理分析input觸發ANR的原理3理解Android ANR的信息收集過程AMS.appNotResponding過程分析,收集traces4解讀Java進程的Trace文件kill -3 信息收集過程5Native進程之Trace原理debuggerd -b 信息收集過程6WatchDog工作原理WatchDog觸發機制7理解Java Crash處理流程AMS.handleApplicationCrash過程分析8理解Native Crash處理流程debuggerd守護進程9global reference限制策略global reference

4.3 Android進程系列

進程/線程是操作系統的魂,各種服務、組件、子系統都是依附於具體的進程實體。深入理解進程機制對於掌握Android系統整體架構和運轉機制是非常有必要的,是系統工程師的基本功,下面列舉進程相關的文章:

序號文章名概述1理解Android進程創建流程Process.start過程分析2理解殺進程的實現原理Process.killProcess過程分析3Android四大組件與進程啟動的關係AMS.startProcessLocked過程分析組件與進程4Android進程絕殺技--forceStopforce-stop過程分析徹底移除組件與殺進程5理解Android線程創建流程3種不同線程的創建過程6徹底理解Android Binder通信架構以start-service為線,闡述進程間通信機理7理解Binder線程池的管理Zygote fork的進程都默認開啟binder線程池8Android進程生命周期與ADJ進程adj, processState以及lmk9Android LowMemoryKiller原理分析lmk原理分析10進程優先順序進程nice,thread priority以及scheduler11Android進程調度之adj演算法updateOomAdjLocked過程12Android進程整理整理系統的所有進程/線程

4.4 四大組件系列

對於App來說,Android應用的四大組件Activity,Service,Broadcast Receiver, Content Provider最為核心,接下分別展開介紹:

序號文章名類別1startActivity啟動過程分析Activity2簡述Activity生命周期Activity3startService啟動過程分析Service4bindService啟動過程分析Service5以Binder視角來看Service啟動Service6Android Broadcast廣播機制分析Broadcast7理解ContentProvider原理ContentProvider8ContentProvider引用計數ContentProvider9Activity與Service生命周期Activity&&Service10簡述Activity與Window關係Activity&&Window11四大組件之綜述AMS12四大組件之ServiceRecordService13四大組件之BroadcastRecordBroadcast14四大組件之ContentProviderRecordContentProvider15理解Android ContextContext16理解Application創建過程Application17unbindService流程分析Service18四大組件之ActivityRecordActivity19AMS總結(一)AMS

4.5 圖形系統系列

圖形也是整個系統非常複雜且重要的一個系列,涉及WindowManager,SurfaceFlinger服務。

序號文章名類別1WindowManager啟動篇(http://gityuan.com/2017/01/08/windowmanger/)Window2WMS之啟動窗口篇(http://gityuan.com/2017/01/15/wms_starting_window/)Window3以Window視角來看startActivity(http://gityuan.com/2017/01/22/start-activity-wms/)Window4Android圖形系統概述(http://gityuan.com/2017/02/05/graphic_arch/)SurfaceFlinger5SurfaceFlinger啟動篇(http://gityuan.com/2017/02/11/surface_flinger/)SurfaceFlinger6SurfaceFlinger繪圖篇(http://gityuan.com/2017/02/18/surface_flinger_2/)SurfaceFlinger7Choreographer原理(http://gityuan.com/2017/02/25/choreographer/)Choreographer

4.6 系統服務篇

再則就是在整個架構中有大量的服務,都是基於Binder來交互的,Android系統服務的註冊過程也是在此之上的構建的。計劃針對部分核心服務來重點分析:

  • AMS服務
  • AMS啟動過程(一)(http://gityuan.com/2016/02/21/activity-manager-service/)
  • 更多組件篇[見小節4.3]
  • Input系統
  • Input系統—啟動篇(http://gityuan.com/2016/12/10/input-manager/)
  • Input系統—InputReader線程(http://gityuan.com/2016/12/11/input-reader/)
  • Input系統—InputDispatcher線程(http://gityuan.com/2016/12/17/input-dispatcher/)
  • Input系統—UI線程(http://gityuan.com/2016/12/24/input-ui/)
  • Input系統—進程交互(http://gityuan.com/2016/12/31/input-ipc/)
  • Input系統—ANR原理分析(http://gityuan.com/2017/01/01/input-anr/)
  • PKMS服務
  • PackageManager啟動篇(http://gityuan.com/2016/11/06/packagemanagerservice)
  • Installd守護進程(http://gityuan.com/2016/11/13/android-installd)
  • Alarm服務
  • 理解AlarmManager機制(http://gityuan.com/2017/03/12/alarm_manager_service/)
  • JobScheduler服務
  • 理解JobScheduler機制(http://gityuan.com/2017/03/10/job_scheduler_service/)
  • BatteryService
  • Android耗電統計演算法(http://gityuan.com/2016/01/10/power_rank/)
  • PMS服務
  • DropBox服務
  • DropBoxManager啟動篇(http://gityuan.com/2016/06/12/DropBoxManagerService/)
  • UserManagerService
  • 多用戶管理UserManager(http://gityuan.com/2016/11/20/user_manager/)

4.7 內存&&存儲篇

  • 內存篇
  • Android LowMemoryKiller原理分析(http://gityuan.com/2016/09/17/android-lowmemorykiller/)
  • Linux內存管理(http://gityuan.com/2015/10/30/kernel-memory/)
  • Android內存分析命令(http://gityuan.com/2016/01/02/memory-analysis-command/)
  • 存儲篇
  • Android存儲系統之源碼篇:http://gityuan.com/2016/07/17/android-io/
  • Android存儲系統之架構篇:http://gityuan.com/2016/07/23/android-io-arch
  • Linux驅動篇
  • 敬請期待
  • dalvik/art
  • 解讀Java進程的Trace文件:http://gityuan.com/2016/11/26/art-trace/

4.8 工具篇

再來說說Android相關的一些常用命令和工具以及調試手段。

序號文章名類別1理解Android編譯命令(http://gityuan.com/2016/03/19/android-build/)build2理解Android.bp(http://gityuan.com/2018/06/02/android-bp/)build2性能工具Systrace(http://gityuan.com/2016/01/17/systrace/)systrace3Android內存分析命令(http://gityuan.com/2016/01/02/memory-analysis-command/)Memory4ps進程命令(http://gityuan.com/2015/10/11/ps-command/)Process5Am命令用法(http://gityuan.com/2016/02/27/am-command/)Am6Pm命令用法(http://gityuan.com/2016/02/28/pm-command/)Pm7調試系列1:bugreport源碼篇(http://gityuan.com/2016/06/10/bugreport/)bugreport8調試系列2:bugreport實戰篇(http://gityuan.com/2016/06/11/bugreport-2/)bugreport9dumpsys命令用法(http://gityuan.com/2016/05/14/dumpsys-command/)dumpsys10Android logd日誌原理(http://gityuan.com/2018/01/27/android-log/)logd11介紹gdb調試工具(http://gityuan.com/2017/09/09/gdb/)gdb12介紹addr2line調試命令(http://gityuan.com/2017/09/02/addr2line/)addr2line

4.9 實戰篇

下面列舉處理過的部分較為典型的案例,供大家參考:

序號文章名類別1Binder Driver缺陷導致定屏的案例(http://gityuan.com/2018/05/12/binder-driver-bug/)binder2深度解讀ArrayMap優勢與缺陷(http://gityuan.com/2019/01/13/arraymap/)ArrayMap3數組越界導致系統重啟的案例(http://gityuan.com/2018/02/10/reboot-locked-method/)數組越界4一行Log引發多線程並發問題的案例(http://gityuan.com/2018/02/03/log-fc/)多線程並發5跑monkey壓力測試過程的凍屏案例(http://gityuan.com/2018/02/17/monkey-deadlock/)monkey凍屏6深度剖析APP保活案例(http://gityuan.com/2018/02/24/process-keep-forever/)保活

結束語

Android系統之博大精深,包括Linux內核、Native、虛擬機、Framework,通過系統調用連通內核與用戶空間,通過JNI打通用戶空間的Java層和Native層,通過Binder、Socket、Handler等打通跨進程、跨線程的信息交換。只有真正閱讀並理解系統核心架構的設計,解決問題和設計方案才能做到心中無劍勝有劍,才能做到知其然知其所以然。當修鍊到此,恭喜你對系統有了更高一個層次的理解,正如太極劍法,忘記了所有招式,也就練成了太極劍法。

再回過頭去看看那些API,看到的將不再是一行行代碼、一個個介面的調用,而是各種信息的傳遞與交互工作,而是背後成千上萬個小蝌蚪的動態執行流。記得《俠客行》裡面的龍木二島主終其一生也無法參透太玄經,石破天卻短短數日練成絕世神功,究其根源是龍木二島主以靜態視角去解讀太玄經,而石破天把牆壁的圖案想像成無數遊動的蝌蚪,最終成就絕世神功。一言以蔽之,程序代碼是死的,系統運轉是活的,要以動態視角去理解系統架構。

作者:袁輝輝,安卓知名博主Gityuan,現就職於手機廠商,熱衷於研究Android系統架構與內核技術,對Android系統框架有著深刻理解與豐富的實戰經驗。

聲明:本文為作者投稿,版權歸對方所有,如需轉載請聯繫原作者。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

軟體開發團隊中,憑什麼新手當道?| 暢言

TAG:CSDN |