Android App 啟動流程:
當你想要啟動一個app時,首先得點擊該app桌面圖標。那點擊圖標時到底發生了什么呢?先看個理論知識
- .Launcher: launcher其實就是一個app,從功能上說,是對手機上其他app的一個管理和啟動,從代碼上說比其他app多了一個屬性,就是在AndroidManifest.xml文件中多了一個
< category android:name="android.intent.category.HOME" />
屬性,這個屬性就是在啟動系統或者按Home鍵時會過濾這個屬性,如果系統中只要一個應用具有這個屬性,就會直接跳轉到這個界面,也就是這個launcher,如果有多個,會彈出選擇框讓用戶選擇并且提示用戶是否選擇默認設置。也就是Launcher就是我們的桌面,他就是個系統的App。我們點擊的每個程序圖標就是他的一個item,會觸發onclick事件,接受時間后然后Launcher會打開我們的應用。 - zygote: zygote意為“受精卵“。Android是基于Linux系統的,而在Linux中,所有的進程都是由init進程直接或者是間接fork出來的,zygote進程也不例外。在Android系統里面,zygote是一個進程的名字。Android是基于Linux System的,當你的手機開機的時候,Linux的內核加載完成之后就會啟動一個叫“init“的進程。在Linux System里面,所有的進程都是由init進程fork出來的,我們的zygote進程也不例外。
我們都知道,每一個App其實都是:一個單獨的dalvik虛擬機 、一個單獨的進程 。 所以當系統里面的第一個zygote進程運行之后,在這之后再開啟App,就相當于開啟一個新的進程。而為了實現資源共用和更快的啟動速度,Android系統開啟新進程的方式,是通過fork第一個zygote進程實現的。所以說,除了第一個zygote進程,其他應用所在的進程都是zygote的子進程,這下你明白為什么這個進程叫“受精卵”了吧?因為就像是一個受精卵一樣,它能快速的分裂,并且產生遺傳物質一樣的細胞! - SystemServer: SystemServer也是一個進程,而且是由zygote進程fork出來的。 知道了SystemServer的本質,我們對它就不算太陌生了,這個進程是Android Framework里面兩大非常重要的進程之一——另外一個進程就是上面的zygote進程。為什么說SystemServer非常重要呢? 因為系統里面重要的服務都是在這個進程里面開啟的,比如
ActivityManagerService、PackageManagerService、WindowManagerService
等等。 - ActivityManagerService: ActivityManagerService,簡稱AMS,服務端對象,負責系統中所有Activity的生命周期。 ActivityManagerService進行初始化的時機很明確,就是在SystemServer進程開啟的時候,就會初始化ActivityManagerService。
- Instrumentation和ActivityThread: 每個Activity都持有Instrumentation對象的一個引用,但是整個進程只會存在一個Instrumentation對象。Instrumentation這個類里面的方法大多數和Application和Activity有關,這個類就是完成對Application(應用程序)和Activity初始化和生命周期的工具類。Instrumentation這個類很重要,對Activity生命周期方法的調用根本就離不開他,他可以說是一個大管家。ActivityThread,就是UI線程。App和AMS是通過Binder傳遞信息的,那么ActivityThread就是專門與AMS的外交工作的。
流程圖:
總結:
- Launcher進程: 你點擊的桌面app進程 整個App啟動流程的起點,負責接收用戶點擊屏幕事件,它其實就是一個Activity,里面實現了點擊事件,長按事件,觸摸等事件,可以這么理解,把Launcher想象成一個總的Activity,屏幕上各種App的Icon就是這個Activity的button,當點擊Icon時,會從Launcher跳轉到其他頁面
- SystemServer進程: 這個進程在整個的Android進程中是非常重要的一個,地位和Zygote等同,它是屬于Application Framework層的,Android中的所有服務,例如AMS, WindowsManager, PackageManagerService等等都是由這個SystemServer fork出來的。所以它的地位可見非同一般
- App進程: 你要啟動的App所運行的進程
還要涉及六個大類:
- ActivityManagerService:(AMS)AMS是Android中最核心的服務之一,主要負責系統中四大組件的啟動、切換、調度及應用進程的管理和調度等工作,其職責與操作系統中的進程管理和調度模塊相類似,因此它在Android中非常重要,它本身也是一個Binder的實現類。
- Instrumentation:監控應用程序和系統的交互
- ActivityThread: 應用的入口類,通過調用main方法,開啟消息循環隊列。ActivityThread所在的線程被稱為主線程
- ApplicationThread: ApplicationThread提供Binder通訊接口,AMS則通過代理調用此App進程的本地方法
- ActivityManagerProxy: AMS服務在當前進程的代理類,負責與AMS通信。
- ApplicationThreadProxy: ApplicationThread在AMS服務中的代理類,負責與ApplicationThread通信。
- 可以說,啟動的流程就是通過這六個大類在這三個進程之間不斷通信的過程
啟動流程:
- ①點擊桌面App圖標,Launcher進程采用Binder IPC向system_server進程發起startActivity請求;
- ②system_server進程接收到請求后,向zygote進程發送創建進程的請求;
- ③Zygote進程fork出新的子進程,即App進程;
- ④App進程,通過Binder IPC向sytem_server進程發起attach Application(附加的應用程序)請求;
- ⑤system_server進程在收到請求后,進行一系列準備工作后,再通過binder
IPC向App進程發送schedule LaunchActivity(安排計劃發射活動)請求; - ⑥App進程的binder線程(ApplicationThread)在收到請求后,通過handler向主線程發送LAUNCH_ACTIVITY消息;
- ⑦主線程在收到Message后,通過發射機制創建目標Activity,并回調Activity.onCreate()等方法。
- ⑧到此,App便正式啟動,開始進入Activity生命周期,執行完onCreate/onStart/onResume方法,UI渲染結束后便可以看到App的主界面。
補充App的啟動過程:
當Launcher進程,檢測到用戶觸摸到某個App的時候,整個軟件里面最應該被加載的第一個文件是:AndroidMnifest.xml
,首先它會檢測機器的SDK版本(手機的android也是有SDK版本號的)能否承載這個App,這個在代碼里面有設置:<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" />
有的時候如果機器不滿足安裝就裝不上,有的是安裝能裝上但是不能運行。再來就是去獲取app所需要的的一些權限,比如說網絡請求:<uses-permission android:name="android.permission.INTERNET"/>
,還有就是一個App有那么多界面,具體要啟動哪一個要看<intent-filter>
這個標簽在哪一個<activity>
標簽里面,下圖代表第一個要加載的界面是:MainActivity
- (SDK(Software Development Kit 軟件開發工具),Android SDK 顧名思義,就是專門用于開發Android 應用的工具包.只有通過Android SDK 我們才可以開發運行在Android 系統中的應用,比如說創建頁面/服務等.)
- app和linux的程序類似,需要相應的依賴庫,1個android系統默認都會集成你需要的依賴,如果沒有,就需要你的apk里里添加相應庫,andoroid本質就是一個復雜的linux系統,這么理解會更好理解。
如果這時候創建另外一個界面:
創建完成后,可以看到
R.java
里面(存放控件、界面等等的ID)多了activity_other的ID,并且res下面多了activity_other.xml
這個布局文件。然后將這個布局界面設置為啟動的第一個界面:
然后再介紹.java`文件里面的代碼:
activity是一個界面,我們創建的MainActivity是繼承自activity,所以MainActivity還是一個界面,這個界面有一些生成周期, onCreate
是代表這個界面被創建,通過AndroidMainfest.xml
確認了這個界面會不會被加載,如果這個界面被加載然后這個onCreate入口會自動的被操作系統拿來執行,其實就像之前寫的main函數,是一個入口,之后的一些列開發,會在這個函數里面進行。super.onCreate(savedInstanceState)
會調用父類的onCreate去創建一個空白的界面,去做一些頁面初始化(由系統去做)。
setContentView(R.layout.activity_main)
表示將這個java文件和activity_main這個布局文件關聯起來。是通過ID的方式讓java文件和xml文件進行關聯。
R.java
里面存放了activity_main界面的ID:
Android六大基本布局:
Android六大基本布局分別是:線性布局LinearLayout、表格布局TableLayout、相對布局RelativeLayout、層布局FrameLayout、絕對布局AbsoluteLayout、網格布局GridLayout。其中,表格布局是線性布局的子類。網格布局是Android4.0新增的,在手機程序設計中,絕對布局基本上不用,用得相對較多的是線性布局和相對布局。
學習基本布局要理解兩個比較基礎概念的圖:
-
Android布局管理器的類圖:
上面這個類圖只是說了六大基本布局的關系,其實ViewGroup還有其他一些布局管理器。這里要理解一點就是布局也是布局管理器,因為布局里面還可以添加布局。
-
Android布局的XML關系圖:
第二個圖說的是:布局管理器里面既可以添加多個布局管理器又可以添加多個控件,而控件里面不能再添加布局或控件了。
界面顯示一張圖片:
參考博文: 安卓App的啟動過程