Android AMS服務


繼續來研究Android Framework層相關的一些東東,這里是以Android8.0版本的源碼進行梳理的,關注的還是其核心流程,不是徹底分析,了解了核心流程是為了了期其大概的原理。

Android系統啟動:

這里具體就不分析代碼了,因為重點是來分析AMS相關的代碼,這里以流程圖的方式來展現一下整個的啟動,畢境對於一個組件的啟動得要建立在整個Android系統啟動基礎之上的,另外這塊的具體源碼也不敢看,還沒達到這種能直接分析底層的能力,所以先從大局觀來了解其流程,下面開始:

 接着就啟動Linux內核了:

 然后再啟動init進程:

接着則啟動咱們熟知的Zygote進程了:

接下來則啟動各種服務了:

而其中當啟動了AMS服務之后,則就會啟動Launch應用程序了,如下:

我們知道以上服務最終都得到ServiceManager進行注冊,因為其實都是一個Binder通信的過程,所以再來復習一下ServiceManager的啟動流程。

Binder機制ServiceManager啟動:

 

那知道了ServiceManager何時啟動的,接下來重點來看一下咱們這次要研究的AMS(ActivityManagerService)它是怎么注冊ServiceManager上的。

AMS注冊流程:

其中ServiceManager就是一個服務端的角色,而AMS則是一個客戶端的角色。

應用程序啟動:

在知道了AMS服務器注冊過程之后,接下來則看一下一個Android應用是如何啟動的,先來貼一張流程圖:

好,接下來分析一下相關的源碼,看一下是否如流程圖所示,這里還是采用在線的androidxref.com上來進行源碼分析,我電腦本地木有下載,省點事:

首先來看一下Zygote進程的啟動:

然后它里面有一個main主入口函數:

也就是之前Android系統啟動流程圖這塊所示:

最后則開啟死循環來等待Ams的請求,如下:

其實也就是對應這個流程:

好,接下來再來分析一個應用是如何啟動的,按流程圖上的來:

 那就定位到AMS中:

然后:

其中可以看到里面會傳要啟動應用的各種信息:

然后跟進去瞅一眼:

也就是到了這一步:

流程也就到了這:

其中可以看到設置了一系列的參數:

然后再下一步:

對應代碼:

 

 

注意上面是“Zygote主模式”,好,如果這個條件不匹配,則會繼續往下執行,如下:

 

好,如果連接成功,則流程會走到了:

而最終的代碼在這:

此時我們所熟知的ActivityThread的main()方法就會被調用了,然后整個應用就啟動了。

Activity啟動:

根Activity啟動:

這里先回顧一下整個Android系統啟動流程的這一步,串一下:

此時我們點擊Launch應用中的某個圖標,則會啟動該應用的根Activity,其整個流程先看一下流程圖:

好,依據此流程來看一下對應的源代碼:

此時就會創建Application:

 

 最終會調到這:

 

走進去瞅一下它的細節:

 

然后再跟進去:

而對於一些Activity的其它生命周期的啟動都是通過ActivityThread中的Handler來實現的:

普通Activity啟動:

Intrumentation.execStartActivity()【未跨進程】:

對於Activity的啟動我們肯定得要調用startActivity()方法,所以咱們就從這個方法為入口逐一來剖析其里面的機理,還是很復雜的,下面開始:

 

所以接下來看一下Instrumentation的啟動細節:

ActivityManagerProxy.startActivity()【未跨進程】:

而這個ActivityManagerNative在之前https://www.cnblogs.com/webor2006/p/11811650.html分析Binder機制見過,如下:

其實它也是一個典型的AIDL的Binder通信,打開再來瞅一下:

 

然后它里面還有一個Proxy:

此時就會調用到Proxy中的startActivity()方法進行Binder通訊了:

此時就會通過Binder驅動調用它的Stub的onTransact()的方法,如下:

ActivityManagerService.startActivity()【開始跨進程了】:

此時就會調用ActivityManagerService的startActivity方法,因為它是ActivityManagerNative的具體實現類:

此時,就到了跨進程訪問了,在這之前都是在本進程的邏輯,好接下來繼續分析:

ActivityStackSupervisor.startActivityMyWait():

其中看注釋說明,是切換到用戶app的棧了,我們知道Android的Activity是以棧的形式來管理的,所以它是比較核心的了,可以大致看一下它里面有一些棧的管理:

這個棧的管理在之后的分析中還會有提及到,先有個大致印象,先來關注主流程:

而其實又是一個AIDL的過程,進去稍看一下它的細節:

而看一下它具體的實現:

就是從ServiceManager中來找到package相關的服務,標准的AIDL的調用過程,那IPackageManager的具體實現類是哪個呢?其實是這個,也就是繼承了IPackageManager中的抽象類Stub的實現類,其實是它:

PackageManagerService.resolveIntent():掃描app,注冊組件

那看一下它的resolveIntent()方法:

查看一下這個方法的細節:

然后回到resolveIntent()方法來,則會看到有一個根據優先級來選擇最佳的ResolveInfo,如下:

 

好,這里還得再來說一下PackageManagerService這個很重要的服務,主要是管理包的一些信息,我們知道在apk安裝到系統中時,會在/data/app之類的系統目錄下存在,而該服務則會掃描注冊在清單中的一些包信息,那么看一下構造方法就能找到一些相關的信息,如下:

 

所以可以看到該服務器就是來掃描一些包的信息用的,而這構造函數的調用是在這里:

所以這也是為啥在之前這塊可以看到拿服務就是用的"package"這個key,回憶下:

其實Android的很多核心服務都是這樣會往ServiceManager去注冊的。

ActivityStackSupervisor.startActivityLocked():驗證intent、Class、Permission等,保存將要啟動的Activity的Record

好,接下來接着主流程繼續:

那看一下它的細節,可以看到各種異常檢測,這里截其中一小部分:

最終生成一個ActivityRecord對像來保存相關信息:

 

 

ActivityStackSupervisor.startActivityUncheckedLocked():檢查將要啟動的Activity的launchMode和啟動Flag,根據launcheMode和Flag配置task

該方法的實現代碼也比較多,就瞅一下它的大致細節既可:

 

 

里面真的是非常之復雜,也看不懂,有個大體的了解,重點是了解整個主流程的過程,好繼續,直接跳到這方法的最后:

ActvityStack.startActivityLocked:任務棧歷史棧配置

它是專門來維護任務棧的進出的,而上面的ActivityStackSupervisor是維護各個棧的信息,職責不一樣,那下面來看一下該方法的細節:

 

在最后:

此時又回到了ActivityStackSupervisor了,如下:

也就是如下:

ActivityStack.resumeTopActivityInnerLocked():查找要進入暫停的Activity

這個里面實現的代碼理非常之多,只看核心的,在要跳轉到新的Activity之前,先會把一些Activity給暫停了,瞅一下這塊的核心流程:

 

然后在跳到新Activity之前,會先暫停當前的Activity,如下:

ActivityStack.startPausingLocked():通過ipc告訴要暫停的Activity進入暫停

此時看一下這個方法的細節:

而prev.app.thread其實就是ActivityThread,而它里面其實是一個IPC的過程,如下:

 

此時就會到了ActivityThread中的消息處理中心了,如下:

ActivityThread.handlePauseActivity():

下面具體看一下它的實現:

1、正式讓之前的Activity暫停:

 

 

2、告訴AMS已經暫停完成:

回到這個方法繼續執行,就會發現:

而最終會調到ActivityManagerService,如下:

ActivityManagerService.activityPaused():

然后就會調用到ActivityStack.activityPausedLocked()方法。

ActivityStack.activityPausedLocked():

其中這個方法有一個resumeNext參數,傳的true,這里想一想就明白其意思,暫停了當前顯示的Activity之后,那肯定得要將要跳轉的Activity給顯示呀,而這個參數就是控制要顯示跳轉的Activity的邏輯的,如下:

ActivityStackSuperVisor.resumeTopActivitiesLocked():

ActivityStack.resumeTopActivityLocked():驗證是否該啟動的Activity所在進程和app是否存在,若存在,直接啟動,否則,准備創建該進程。

然后在這個方法里面則會有一個關鍵的邏輯判斷,在啟動新的Activity時,先判斷是否該Activity是在同一個進程:

如果為ture則代碼要啟動的Activity為同一個進程,這里就不細看了,如果條件不滿足則代表進程不存在,需要創建進程,這里瞅一下,如下:

ActivityStackSuperVisor.startSpecificActivityLocked():該進程不存在,創建進程

好,又回到了這個棧管理類了,看一下它的細節:

ActivityManagerService.startProcessLocked():通過Process.start(“android.app.ActivityThread”)啟動進程

  

  

ActivityThread.main():

當進程被啟動之后,則該進程的ActivityThread.main()方法就會被執行,這塊就比較熟了。主要是創建一個Looper。 

ActivityThread.attach():

IActivityManager.attachApplication():

而上面的attach的具體實現:

會調用IActivityManager.attachApplication()方法了,此時就會調用ActivityServiceManager.attachApplication(),如下:

然后往這個方法找一下,會有如下核心代碼:

ActivityStackSuperVisor.attachApplicationLocked():准備啟動應用,先查找MainActivity

此時又回到了這個棧管理大管家,瞅下:

ActivityStackSuperVisor.realStartActivityLocked():IPC通知ActivityThread

ActivityThread.scheduleLaunchActivity():

 

其中performLaunchActivity方法就是來創建要啟動的Activity,稍微看一下細節:

至此關於Activity的啟動的主流程就分析完了,太TM復雜了。。可以看到Android底層的代碼有很多C/S架構、分模塊的思想,真的是博大精深。。

Service啟動:

接下來再來分析Android的另一大組件的啟動---Service,先來貼一下大體的主流程圖:

 

好,下面來瞅一下源碼:

具體細節就不看了,最終會調到ActivityThread的這塊:

還有其它相關的一些跟服務相關的東東在里面,大致貼一下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM