android架構(AMS)

Android架構

Android系統啓動過程:Loader -> Kernel -> Native -> Framework -> App

Loader

Boot ROM: 當手機處於關機狀態時,長按Power鍵開機,引導芯片開始從固化在ROM裏的預設出代碼開始執行,然後加載引導程序到RAM
**Boot Loader:**這是啓動Android系統之前的引導程序,主要是檢查RAM,初始化硬件參數等功能。

Kernel

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

Native

啓動init進程(pid=1),是Linux系統的用戶進程,init進程是所有用戶進程的鼻祖。init孵化用戶空間的守護進程、HAL層以及開機動畫等。
init進程會孵化出ueventd、logd、healthd、installd、adbd、lmkd等用戶守護進程。
init進程還啓動servicemanager(binder服務管家)、bootanim(開機動畫)等重要服務。
init進程孵化出Zygote進程,Zygote進程是Android系統的第一個Java進程(即虛擬機進程),Zygote是所有Java進程的父進程,Zygote進程本身是由init進程孵化而來的。

Framework

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

  1. 加載ZygoteInit類,註冊Zygote Socket服務端套接字
  2. 加載虛擬機
  3. preloadClasses
  4. preloadResouces

System Server進程,是由Zygote進程fork而來,System Server是Zygote孵化的第一個進程,System Server負責啓動和管理整個Java framework,包含ActivityManager,PowerManager等服務。
Media Server進程,是由init進程fork而來,負責啓動和管理整個C++ framework,包含AudioFlinger,Camera Service,等服務。

App

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

通信方式

進程/線程之間的通信。
IPC(Inter-Process Communication, 進程間通信)Linux現有管道、消息隊列、共享內存、套接字、信號量、信號這些IPC機制,Android額外還有Binder IPC機制。
Android OS中的Zygote進程的IPC採用的是Socket機制,在上層system server、media server以及上層App之間更多的是採用Binder IPC方式來完成跨進程間的通信。
Handler:對於Android上層架構中,很多時候是在同一個進程的線程之間需要相互通信,例如同一個進程的主線程與工作線程之間的通信,往往採用的Handler消息機制。
Android上層架構,則最常用的通信方式是Binder、Socket、Handler,當然也有少量其他的IPC方式,比如殺進程Process.killProcess()採用的是signal方式。

Binder

現有IPC通訊

  1. 管道:在創建時分配一個page大小的內存,緩存區大小比較有限。
  2. 消息隊列:信息複製兩次,額外的CPU消耗;不合適頻繁或信息量大的通信。
  3. 共享內存:無須複製,共享緩衝區直接付附加到進程虛擬地址空間,速度快;但進程間的同步問題操作系統無法實現,必須各進程利用同步工具解決。
  4. 套接字:作爲更通用的接口,傳輸效率低,主要用於不通機器或跨網絡的通信。
  5. 信號量:常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
  6. 信號: 不適用於信息交換,更適用於進程中斷控制,比如非法內存訪問,殺死某個進程等。

Binder分析

  1. 從性能的角度
    數據拷貝次數:Binder數據拷貝只需要一次,而管道、消息隊列、Socket都需要2次,但共享內存方式一次內存拷貝都不需要;從性能角度看,Binder性能僅次於共享內存。
  2. 從穩定性的角度
    Binder是基於C/S架構的 C/S 相對獨立,穩定性較好。
    共享內存實現方式複雜,沒有客戶與服務端之別, 需要充分考慮到訪問臨界資源的併發同步問題,否則可能會出現死鎖等問題。
  3. 從安全的角度
    傳統Linux IPC的接收方無法獲得對方進程可靠的UID/PID,從而無法鑑別對方身份。傳統IPC只能由用戶在數據包裏填入UID/PID。可靠的身份標記只有由IPC機制本身在內核中添加。傳統IPC訪問接入點是開放的,無法建立私有通道
  4. 從語言層面的角度
    Linux是基於C語言(面向過程的語言),而Android是基於Java語言(面向對象的語句)
    Binder恰恰也符合面向對象的思想 Binder模糊了進程邊界,淡化了進程間通信過程,整個系統彷彿運行於同一個面向對象的程序之中。
    Android OS中的Zygote進程的IPC採用的是Socket(套接字)機制,Android中的Kill Process採用的signal(信號)機制等等。而Binder更多則用在system_server進程與上層App層的IPC交互。

Handler

可以詳見handler源碼分析

系統啓動

進程啓動 概述
init進程 Linux系統中用戶空間的第一個進程, Init.main
zygote進程 所有App進程的父進程, ZygoteInit.main
system_server進程 系統各大服務的載體
servicemanager進程 binder服務的大管家, 守護進程循環運行在binder_loop
app進程 通過Process.start啓動App進程, ActivityThread.main

AMS

AMS啓動

在system_server進程中啓動
SystemServer.java #startBootstrapServices()
創建AMS實例對象,創建Andoid Runtime,ActivityThread和Context對象
setSystemProcess:註冊AMS、meminfo、cpuinfo等服務到ServiceManager
installSystemProviderss,加載SettingsProvider
啓動SystemUIService,再調用一系列服務的systemReady()方法
發佈Binder服務

服務名 類名 功能
activity ActivityManagerService AMS
procstats ProcessStatsService 進程統計
meminfo MemBinder 內存
gfxinfo GraphicsBinder 圖像信息
dbinfo DbBinder 數據庫
cpuinfo CpuBinder CPU
permission PermissionController 權限
processinfo ProcessInfoService 進程服務
usagestats UsageStatsService 應用使用情況

想要查看這些服務的信息,可通過dumpsys <服務名>命令。比如查看CPU信息命令dumpsys cpuinfo

AMS類圖結構

IActivityManager
ActivityManager
ActivityManagerService
以ActivityManager的getRunningServices()函數爲例

public List<RunningServiceInfo> getRunningServices(int maxNum)
            throws SecurityException {
        try {
            return getService()
                    .getServices(maxNum, 0);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

可以看到,調用被委託到了getService.getServices()。

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

實際上調用的是ActivityManagerService中的代碼

  @Override
    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
        enforceNotIsolatedCaller("getServices");

        final int callingUid = Binder.getCallingUid();
        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
        final boolean allowed = mAtmInternal.isGetTasksAllowed("getServices",
                Binder.getCallingPid(), callingUid);
        synchronized (this) {
            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
                allowed, canInteractAcrossUsers);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章