當我們按下電源鍵,Android 究竟做了些什麼?

来源:https://www.cnblogs.com/qcloud1001/archive/2018/11/13/9951168.html
-Advertisement-
Play Games

歡迎大家前往 "騰訊雲+社區" ,獲取更多騰訊海量技術實踐乾貨哦~ 本文由 "goo" 發表於 "雲+社區專欄" 相信我們對Android系統都不陌生,而Android系統博大精深,被各種各樣的智能設備承載的同時,我們會否好奇過,如此複雜的Android究竟是怎麼運作起來的呢?借本文給大家分享,筆者 ...


歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~

本文由goo發表於雲+社區專欄

相信我們對Android系統都不陌生,而Android系統博大精深,被各種各樣的智能設備承載的同時,我們會否好奇過,如此複雜的Android究竟是怎麼運作起來的呢?借本文給大家分享,筆者對Android 系統啟動流程的整體理解~

imghi, I'm Android

現在,按下電源鍵

下麵是Android啟動的核心步驟流程圖,看文字的時候,記得回來對照圖來理解喔,希望閱讀全文後,回觀流程圖,會有恍然大悟的感覺,那麼文章的目的就達到啦~

img整體流程

一、啟動電源及系統啟動

系統從 ROM 中開始啟動,載入引導程式到 RAM ,然後執行。

二、引導程式

引導程式是 Android 操作系統開始運行前的一個小程式,因此它需要針對特定主板與晶元,並不是 Android 操作系統的一部分。引導程式是 OEM 廠商或運行商進行加鎖、限制的地方。

1 兩個階段

  1. 檢測外部 RAM 以及為第二階段載入程式
  2. 設置網路、記憶體等,搭建內核運行環境(為了達到特殊目的時,引導程式可以根據配置參數或者輸入數據來設置內核)

2 引導程式的載入器

Android引導程式可以在\bootable\bootloader\legacy\usbloader找到,傳統的載入器包含的兩個文件:

  1. init.s 初始化堆棧,清零BSS段,會調用 main.c 中的 _main()函數 (bss segment:通常是指用來存放程式中未初始化的全局變數的一塊記憶體區域;BSS - Block Started by Symbol。BSS段屬於靜態記憶體分配)
  2. main.c 初始化硬體,創建 linux 標簽

三、內核啟動

Android 內核啟動方式類似桌面 linux,主要步驟:

1. 設置緩存

2. 被保護存儲器

3. 計劃列表

4. 載入驅動

當內核完成系統設置,接下來即將啟動系統的第一個進程 -- init 進程

四、init 進程

作為 Android 系統的第一個進程,其PID為0,通過解析 init.rc 腳本來構建出系統初始運行形態,這一階段中,“Android” logo 會顯示出來

(系統中,大多數系統服務程式都是在該腳本中描述並被相繼啟動的)

init.rc 由4種類型聲明組成:Actions、Commands、Services、Options

  • Actions:響應某事件的過程。當“trigger”所描述的觸發事件產生時,則依次執行各種“command” 源碼角度:系統會對 init.rc 中各“trigger”進行匹配,當發現符合條件的 Action,就將它加入“命令執行隊列”尾部(除非 Action 已存在隊列中),然後系統再對這些命令按順序進行。on
  • Commands:命令將在所屬事件發生時被一個個執行
  • Services:可執行程式,它們在特定選項的約束下會被 init 程式運行或者重啟(Service 可以在配置中指定是否需要退出重啟,那麼,當 Service 出現異常 crash 時,可有機會複原)service
  • Options:對 service 的約束選項

五和六、 ServiceManager、Zygote、SystemServer

科普:Daemons - 守護進程

init進程通過解析 init.rc 來陸續啟動其他關鍵的系統服務進程,其中最重要的是 ServiceManager、Zygote 和 SystemServer 三者,下麵我們逐一解析:

1 ServiceManager -- Binder 機制支撐者

概述:ServiceManager 是 Binder 機制中的支撐者,負責某 Binder 服務註冊信息到底層 Binder 驅動分配的值解析。

ServiceManager 由 init 進程解析 rc 腳本時啟動,屬於 core 類,其他同類進程包括:uenetd、console、adbd等。根據 core 組的特性,這些進程會同時啟動或停止。另外,ServiceManager 配置含有 critical 屬性,這意味著它是系統關鍵進程(如果進程不幸在4分鐘內異常退出超過4次,設備將重啟併進入還原模式)。當 ServiceManager 每次重啟時,其他關鍵進程:zygote、media、surfaceflinger 等也會被 restart。

2. Zygote -- “孕育”新線程與進程

Android 中大多數應用進程與系統進程都是通過 Zygote 來生成的。Zygote 同樣由 init 解析 rc 腳本時啟動,屬於 main 類,同屬 main 類的系統進程有:netd、debuggerd、rild等。Zygote並不是處於獨立的程式中的,它所在程式名為“app_process”,觀察 app_process 主函數實現知道,如果 init.rc 中指定了 --zygote選項,app_process 接下來將啟動“ZygoteInit”,並傳入“start-system-server”,這樣,ZygoteInit 就會運行在虛擬機上(Dalvik VM)上了。

  • ZygoteInit 函數有兩項重要工作

  • 預裝載各種系統類

  • 搭建 SystemServer 環境,並啟動 SystemServer(大部分的 Android 系統服務都在其中,由 Java 編寫)

  • ZygoteInit 流程總結

    摘自:Gityuan -- Android 系統啟動-Zygote 篇

    1. 解析init.zygote.rc中的參數,創建AppRuntime並調用AppRuntime.start()方法;
    2. 調用AndroidRuntime的startVM()方法創建虛擬機,再調用startReg()註冊JNI函數;
    3. 通過JNI方式調用ZygoteInit.main(),第一次進入Java世界;
    4. registerZygoteSocket()建立socket通道,zygote作為通信的服務端,用於響應客戶端請求;
    5. preload()預載入通用類、drawable和color資源、openGL以及共用庫以及WebView,用於提高ap啟動效率;
    6. zygote完畢大部分工作,接下來再通過startSystemServer(),fork得力幫手system_server進程,也是上層framework的運行載體。
    7. zygote功成身退,調用runSelectLoop(),隨時待命,當接收到請求創建新進程請求時立即喚醒並執行相應工作。

ZygoteInit 結束後,開機Logo就出來了。

(註意:這裡並不包括開機動畫,而是開機前 “Android” Logo 出現的那個畫面,開機動畫出現之前還需要進行各種載入,開機動畫是在“Android” Logo 出現之後才播放的)

3. SystemServer -- 大部分 Android 系統服務所在地

SystemServer 是 Android 進入 Launcher 前的最後準備,它提供了眾多的由“Java”語言編寫的系統服務

如果 init.rc 中為 zygote 指定啟動參數 --start-system-server,那麼 ZygotyeInit 就會調用 startSystemServer 來進入 SystemServer。

  • startSystemServer函數解析:
  • 首先 ZygoteInit 通過 Zygote.forkSystemServer 來生成一個新的線程(fork),用於承載各種系統服務。(源碼角度:Zygote 內部由 Native 函數 Dalvik_dalvik_system_Zygote_forkSystemServer 來進一步實現,最終調用底層介面的 fork 介面來實際產生進程)
  • 根據fork特性,子進程與父進程將獲得相同的代碼環境pid為0為子進程,否則為父進程;如果是前者,則進一步調用 handleSystemServerProcess(parseArgs) 函數來完成最核心的工作 -- “啟動各系統服務”(源碼角度:handleSystemServerProcess 方法將 startSystemServer 中的 parsedArgs.remainingArgs 參數傳給 RuntimeInit.zygoteInit,後者又調用 nativeZygoteInit 函數
  • nativeZygoteInit 調用後,接著,三個重要的 static 函數就要被執行了:init1 - 完成本地Service(SurfaceFlinger、AudioFlinger等)啟動,完成後調用 init2init2 - 新建一個新的帶 Looper 的線程 ServerThread來啟動 Java層各 Service

後語

上面對 Android 系統啟動做了一個簡述,意在給大家展現一個整體流程,其中每個環節涉及的知識點只是淺淺掠過,筆者也尚在學習與探索中,希望在後續再作詳細分析。

資源推薦

相關閱讀
【每日課程推薦】機器學習實戰!快速入門線上廣告業務及CTR相應知識

此文已由作者授權騰訊雲+社區發佈,更多原文請點擊

搜索關註公眾號「雲加社區」,第一時間獲取技術乾貨,關註後回覆1024 送你一份技術課程大禮包!

海量技術實踐經驗,盡在雲加社區


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 mycat介紹 中間件:代理; 面向企業的開源的大的資料庫集群,性能極高;淘寶正在使用; 1.1 資料庫中間件歷史: amoeba:變形蟲 缺點:分散式高可用結構不穩定 cobar:mycat前身 缺點:cobar容易出現後端物理伺服器的假死現象 2 資料庫中間件的原理 3 mycat特點: 1 ...
  • 近年來,大數據以迅猛的發展速度滲透進人們生活的方方面面。大數據是信息化發展的新階段,隨著信息技術和人類生產生活交匯融合,互聯網飛速普及,全球數據呈現爆發增長、海量集聚的特點,對經濟發展、社會治理、人民生活都產生了重大影響。大數據掀起了科技發展的浪潮,學習大數據的人越來越多,由之前的電腦專業逐漸像零 ...
  • 1 讀寫分離 在資料庫分散式集群中,從節點從邏輯上是不能寫數據的,但是也不讀的話會造成資源的浪費; 分析: 集群中從節點具有數據同步的效果,可以完成對外的讀服務,從節點的整體數量一般來講大於主節點;讀的服務比例大於寫的服務;一旦讀寫分離實現,集群的性能就可以得到極大的提升; 2 高可用替換 分散式數 ...
  • linux下多台mysql的安裝,主從關係的配置,實現單機熱備,雙機熱備 ...
  • SQL Server的日誌傳送(log shipping)技術一直比較雞肋,尤其當SQL Server 推出了Always On技術以後,估計使用日誌傳送(log shipping)這種技術方案的企業越來越少,但是日誌傳送也有自己的一些優點,有些特殊場景或業務背景下也有其存在的價值。最近由於特殊業務... ...
  • Intent的用法 意圖的分類和用法: 隱式意圖:通過指定一組數據或者動作實現 顯示意圖:通過指定具體的activity實現 意圖的用途: 顯示意圖用於開啟自己應用內的Activity. 隱式意圖用於開啟其他應用的Activity(主要是系統應用),相比顯示意圖安全性較差. 意圖的實現: 通過Int ...
  • 歡迎大家前往 "騰訊雲+社區" ,獲取更多騰訊海量技術實踐乾貨哦~ 本文由 "落影" 發表於 "雲+社區專欄" 前言 app在渲染視圖時,需要在坐標系中指定繪製區域。 這個概念看似乎簡單,事實並非如此。 When an app draws something in iOS, it has to lo ...
  • 最近公司要在APP上添加一個人臉識別功能,在網上搜了一圈,發現虹軟的人臉識別SDK挺好用的,而且還免費,所以就下載了他們的SDK研究了一下。總的來看功能挺好用的,只是demo上面部分功能不是很完善,所以就在官方demo的基礎上改動了一些小的功能。 新增功能:1. 通過圖片註冊人臉2. 增加列表頁面可 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...