1. 程式人生 > >android 從點選圖示到啟動Activity的流程

android 從點選圖示到啟動Activity的流程

一、前期準備

1.一些概念的介紹

ActivityManagerServices,簡稱AMS,服務端物件,負責系統中所有Activity的生命週期

ActivityThread,App的真正入口。當開啟App之後,會呼叫main()開始執行,開啟訊息迴圈佇列,這就是傳說中的UI執行緒或者叫主執行緒。與ActivityManagerServices配合,一起完成Activity的管理工作

ApplicationThread,用來實現ActivityManagerService與ActivityThread之間的互動。在ActivityManagerService需要管理相關Application中的Activity的生命週期時,通過ApplicationThread的代理物件與ActivityThread通訊。

ApplicationThreadProxy,是ApplicationThread在伺服器端的代理,負責和客戶端的ApplicationThread通訊。AMS就是通過該代理與ActivityThread進行通訊的。

Instrumentation,每一個應用程式只有一個Instrumentation物件,每個Activity內都有一個對該物件的引用。Instrumentation可以理解為應用程序的管家,ActivityThread要建立或暫停某個Activity時,都需要通過Instrumentation來進行具體的操作。

ActivityStack,Activity在AMS的棧管理,用來記錄已經啟動的Activity的先後關係,狀態資訊等。通過ActivityStack決定是否需要啟動新的程序。

ActivityRecord,ActivityStack的管理物件,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其他的管理資訊。其實就是伺服器端的Activity物件的映像。

TaskRecord,AMS抽象出來的一個“任務”的概念,是記錄ActivityRecord的棧,一個“Task”包含若干個ActivityRecord。AMS用TaskRecord確保Activity啟動和退出的順序。如果你清楚Activity的4種launchMode,那麼對這個概念應該不陌生。

2.android啟動過程中的一些東西

1)zygote是什麼?有什麼作用?

zygote意為“受精卵“。Android是基於Linux系統的,而在Linux中,所有的程序都是由init程序直接或者是間接fork出來的,zy我們都知道,每一個App其實都是

  • 一個單獨的dalvik虛擬機器
  • 一個單獨的程序

所以當系統裡面的第一個zygote程序執行之後,在這之後再開啟App,就相當於開啟一個新的程序。而為了實現資源共用和更快的啟動速度,Android系統開啟新程序的方式,是通過fork第一個zygote程序實現的。所以說,除了第一個zygote程序,其他應用所在的程序都是zygote的子程序,這下你明白為什麼這個程序叫“受精卵”了吧?因為就像是一個受精卵一樣,它能快速的分裂,並且產生遺傳物質一樣的細胞

2)SystemServer是什麼?怎麼啟動的

SystemServer也是一個程序,而且是由zygote程序fork出來的。

系統裡面重要的服務都是在這個程序裡面開啟的,比如ActivityManagerService、 PackageManagerService、WindowManagerService等等

具體啟動過程:

  1. 在zygote開啟的時候,會呼叫ZygoteInit.main()進行初始化,會呼叫startSystemServer()。
  2. startSystemServer()方法中會fork SystemServer。

3)ActivityManagerService的啟動

  1. 在SystemServer程序開啟的時候,就會初始化ActivityManagerService。
  2. 在startBootstrapServices()中完成初始化(這個方法還完成了許多系統重要服務的初始化)。
  3. 在這之前的createSystemContext()方法中已經完成了ActivityThread的建立

二、啟動Activity的正式流程

第一步:launcher程序通知AMS自己想要啟動一個應用的主activity,其中Launcher和AMS的通訊使用了跨程序技術,流程圖如下,其中ActivityManagerProxy是AMS的遠端介面;

  1. 首先我們需要了解到的就是Launcher本質上也是一個應用程式,和我們的App一樣,也是繼承自Activity。
  2. 而我們在桌面上的圖示本質上是一個BubbleTextView物件,除了在桌面上有圖示之外,在程式列表中點選圖示,也可以開啟對應的程式,這個圖示是一個PagedViewIcon物件。
  3. 所以點選桌面圖示實際呼叫的就是BubbleTextView的點選事件。而該電機事件實際呼叫的就是Launcher中的startActivitySafelf()方法,而startActivitySafely()方法,實際上是呼叫了StartActivity方法,所以我們現在明確了,Launcher中開啟一個App,其實和我們在Activity中直接startActivity()基本一樣,都是呼叫了Activity.startActivityForResult()。
  4. 而在startActivityForResult()方法中實際上還是呼叫了mInstrumentation.execStartActivity()這個方法,
  5. 所以當我們在程式中呼叫startActivity()的 時候,實際上呼叫的是Instrumentation的相關的方法(execStartActivity)。
  6. Instrumentation這個類很重要,對Activity生命週期方法的呼叫根本就離不開他,而具體怎麼呼叫,那就要看ActivityThread的了(包括暫停,啟動Activity等)。
  7. 而execStartActivity()這個方法中實際上又是呼叫了ActivityManagerNative.getDefault() .startActivity方法,而這裡的ActivityManagerNative.getDefault返回的就ActivityManagerService的遠端介面,即ActivityManagerProxy,而這裡進行的就是IPC通訊,利用Binder物件,呼叫transact(),把所有需要的引數封裝成Parcel物件,向AMS傳送資料進行通訊。
  8. 到這裡就完成了向AMS發出啟動Activity的請求

第二步:AMS收到啟動activity的請求後會調整一下自身的狀態(為後面啟動新的activity做準備)並要求Launcher當前棧頂的activity進入pause狀態,流程圖如下,其中ApplicationThreadProxy是ApplicationThread的遠端介面;

第三步:Launcher pause完當前棧頂activity後通知AMS可以開始啟動新activity了,因為這是一個待啟動程序的主activity,因此AMS要先啟動一個新的程序然後才能在新的程序中完成啟動主activity的任務,其中Process.start介面會載入一個ActivityThread類並呼叫其main方法啟動一個新的程序,此時Launcher基本完成任務,後面主要是新程序和AMS的互動來完成activity的真正啟動,流程圖如下;

第四步:新的程序啟動後會通過呼叫attachApplication與AMS建立關聯,AMS也會將該程序相關的一些資訊儲存起來以便於後期管理,準備就緒後AMS會通過ApplicationThread的遠端介面ApplicationThreadProxy來呼叫scheduleLaunchActivity通知新程序開始真正啟動activity的工作了,activity的onCreate和onResume函式都是在ActivityThread的handleLaunchActivity中完成的

這篇文章是我在學習安卓activity啟動過程中做的一些總結,文章內容和圖片都是總結自

這裡自己就是做個小筆記,個人認為這樣看著更方便些,我這裡就沒有貼原始碼了,想看原始碼的可以去那兩篇博文中結合自己的實際情況去看