Android 啟動流程分析

來源:互聯網
上載者:User

標籤:sys   .com   訊息迴圈   ant   分配   建立   ssr   連結   第一個   

原文:https://www.jianshu.com/p/a5532ecc8377

 

作者曾經在高通的Android效能組工作,主要工作是最佳化Android Application的啟動時間。

 

  1. APP基礎理論

    要想最佳化App啟動時間, 第一步就是瞭解App啟動進程的工作原理. 有幾個基礎理論:

    Android Application與其他移動平台有兩個重大不同點:

    1. 每個Android App都在一個獨立空間裡,意味著其運行在一個單獨的進程中,擁有自己的VM,

      被系統分配一個唯一的user ID

    2. Android APP由很多不同的組件組成,這些組件還可以啟動其他APP的組件,因此,android APP

      並沒有一個類似程式入口的main()方法

    Android application組件包括:

    Activity:前台介面,直接面向User,提供UI和操作

    Service:背景工作

    Broadcast Receivers:廣播接受者

    Context Providers:資料提供者

Android進程和Linux進程一樣,預設情況下,每個apk運行在自己的Linux進程中,另外,預設一個進程裡面只有一個線程=主線程。

這個主線程中有一個Looper執行個體,通過調用Looper.loop()從Message隊列裡面取出Message來做相應的處理

那麼,這個進程何時啟動合適啟動的呢?

簡單來說,進程在其需要的時候被啟動,任意時候,當使用者或者其他組件調取你的apk中的任意組件時,如果你的apk此時沒有運行,

系統會為其建立一個信心的進程並啟動。通常,這個進程會持續運行直到被系統殺死。關鍵是:進程時在被需要的時候才建立的。

舉個例子,如果你點擊email中的超連結, 會在瀏覽器裡面開啟一個網頁. Email App和瀏覽器App是兩個不同的App, 運行在不同的進程中.

這次點擊事件促使Android系統去建立了一個新的進程來執行個體化瀏覽器的組件.

首先, 讓我們快速看下Android啟動流程. 與眾多基於Linux核心的系統類別似, 啟動系統時, bootloader啟動核心和init進程. init進程分裂出更多名為"daemons(守護進程)"的底層的Linux進程, 諸如android debug deamon, USB deamon等. 這些守護進程處理底層硬體相關的介面.

 

隨後, init進程會啟動一個非常有意思的進程---"Zygote". 顧名思義, 這是一個Android平台的非常基礎的進程. 這個進程初始化了第一個VM, 並且預先載入了framework和眾多App所需要的通用資源. 然後它開啟一個Socket介面來監聽請求, 根據請求孵化出新的VM來管理新的App進程. 一旦收到新的請求, Zygote會基於自身積極式載入的VM來孵化出一個新的VM建立一個新的進程.

 

啟動Zygote之後, init進程會啟動runtime進程. Zygote會孵化出一個超級管理進程---System Server. SystemServer會啟動所有系統核心服務, 例如Activity Manager Service, 硬體相關的Service等. 到此, 系統準備好啟動它的第一個App進程---Home進程了.

 

  1. 啟動APP流程

    使用者點擊Home上的一個APP表徵圖,啟動一個應用時:

    Click事件會調用startActivity(Intent), 會通過Binder IPC機制, 最終調用到ActivityManagerService. 該Service會執行如下操作:

    1. 第一步通過PackageManager的resolveIntent()收集這個intent對象的指向資訊.指向資訊被儲存在一個intent對象中
    2. 下面重要的一步是通過grantURIPermissionLocked()方法來驗證是否有足夠的權利去調用該intent對象指向Activity。
    3. 如果有許可權,ActivityManagerService會檢查並在新的task中啟動目標activity
    4. 現在,是時候檢查這個進程的ProcessRecord是否存在了。如果ProcessRecord是null,ActivityManagerService會建立新的進程來執行個體化目標activity

    2.1建立進程

    ActivityManagerService調用startProcessLocked()方法來建立新的進程, 該方法會通過前面講到的socket通道傳遞參數給Zygote進程. Zygote孵化自身,

    並調用ZygoteInit.main()方法來執行個體化ActivityThread對象並最終返回新進程的pid.

    ActivityThread隨後依次調用Looper.prepareLoop()和Looper.loop()來開啟訊息迴圈.

    流程圖如下:

     

    1. 綁定Application

      接下來要做的就是將進程和指定的Application綁定起來. 這個是通過上節的ActivityThread對象中調用bindApplication()方法完成的.

      該方法發送一個BIND_APPLICATION的訊息到訊息佇列中, 最終通過handleBindApplication()方法處理該訊息. 然後調用makeApplication()方法

      來載入App的classes到記憶體中.

       

      流程圖如下:

    2. 啟動activity

      經過前兩個步驟之後, 系統已經擁有了該application的進程. 後面的調用順序就是普通的從一個已經存在的進程中啟動一個新進程的activity了.

       

      實際調用方法是realStartActivity(), 它會調用application線程對象中的sheduleLaunchActivity()發送一個LAUNCH_ACTIVITY訊息到

      訊息佇列中, 通過 handleLaunchActivity()來處理該訊息.

       

      假設點擊的是一個視頻瀏覽的App, 其流程如下:

Android 啟動流程分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.