Android ActivityManagerService (AMS)總結

轉載前言

AMS在Android中算是比較重要的一個知識點,不管是binder的源碼還是Serveice的源碼,都是涉及到AMS的,因此理解“AMS是什麼”對一個Android開發者來說還是很有必要的。

筆者之前也有分析過相關的源碼:bindService 源碼解析(爲什麼是異步)

已經有博主總結的比較好了,因此就不重開篇幅了。

原文地址:https://github.com/xiangjiana/Android-MS/blob/master/android/ams.md

概述

ActivityManagerService是Framework層的核心服務之一,ActivityManagerService是Binder的子類,它的功能主要以下三點:

  • 四大組件的統一調度
  • 進程管理
  • 內存管理

四大組件的統一調度

ActivityManagerService最主要的功能就是統一的管理者activity,service,broadcast,provider的創建,運行,關閉.我們在應用程序中啓動acitivity,關閉acitiviy等操作最終都是要通過ams來統一管理的.這個過程非常的複雜,不是一下子可以講的清楚的,我這裏推薦老羅的博客來講解四大組件的啓動過程:

  • Android應用程序內部啓動Activity過程(startActivity)的源代碼分析
  • Android系統在新進程中啓動自定義服務過程(startService)的原理分析
  • Android應用程序註冊廣播接收器(registerReceiver)的過程分析
  • Android應用程序發送廣播(sendBroadcast)的過程分析
  • Android應用程序組件Content Provider簡要介紹和學習計劃

AMS中的進程管理

前面曾反覆提到,Android平臺中很少能接觸到進程的概念,取而代之的是有明確定義的四大組件。但是作爲運行在Linux用戶空間內的一個系統或框架,Android不僅不能脫離進程,反而要大力利用Linux OS提供的進程管理機制和手段,更好地爲自己服務。作爲Android平臺中組件運行管理的核心服務,ActivityManagerService當仁不讓地接手了這方面的工作。目前,AMS對進程的管理僅涉及兩個方面:

  • 調節進程的調度優先級和調度策略。
  • 調節進程的OOM值。

App的Crash處理總結

應用進程進行Crash處理的流程。
在這裏插入圖片描述

內存管理

我們知道當一個進程中的acitiviy全部都關閉以後,這個空進程並不會立即就被殺死.而是要等到系統內存不夠時纔會殺死.但是實際上ActivityManagerService並不能夠管理內存,android的內存管理是Linux內核中的內存管理模塊和OOM進程一起管理的.Android進程在運行的時候,會通過Ams把每一個應用程序的oom_adj值告訴OOM進程,這個值的範圍在-16-15,值越低說明越重要,越不會被殺死.當發生內存低的時候,Linux內核內存管理模塊會通知OOm進程根據AMs提供的優先級強制退出值較高的進程.因此Ams在內存管理中只是扮演着一個提供進程oom_adj值的功能.真正的內存管理還是要調用OOM進程來完成.下面通過調用Activity的finish()方法來看看內存釋放的情況.

當我們手動調用finish()方法或者按back鍵時都是會關閉activity的,在調用finish的時候只是會先調用ams的finishActivityLocked方法將當前要關閉的acitiviy的finish狀態設置爲true,然後就會先去啓動新的acitiviy,當新的acitiviy啓動完成以後就會通過消息機制通知Ams,Ams在調用activityIdleInternalLocked方法來關閉之前的acitiviy.

startService流程

總結
在整個startService過程,從進程角度看服務啓動過程

  • Process A進程:是指調用startService命令所在的進程,也就是啓動服務的發起端進程,比如點擊桌面App圖標,此處Process A便是Launcher所在進程。
  • system_server進程:系統進程,是java framework框架的核心載體,裏面運行了大量的系統服務,比如這裏提供ApplicationThreadProxy(簡稱ATP),ActivityManagerService(簡稱AMS),這個兩個服務都運行在system_server進程的不同線程中,由於ATP和AMS都是基於IBinder接口,都是binder線程,binder線程的創建與銷燬都是由binder驅動來決定的,每個進程binder線程個數的上限爲16。
  • Zygote進程:是由init進程孵化而來的,用於創建Java層進程的母體,所有的Java層進程都是由Zygote進程孵化而來;
  • Remote Service進程:遠程服務所在進程,是由Zygote進程孵化而來的用於運行Remote服務的進程。主線程主要負責Activity/Service等組件的生命週期以及UI相關操作都運行在這個線程; 另外,每個App進程中至少會有兩個binder線程 ApplicationThread(簡稱AT)和ActivityManagerProxy(簡稱AMP),當然還有其他線程,這裏不是重點就不提了。

在這裏插入圖片描述

圖中涉及3種IPC通信方式:Binder、Socket以及Handler,在圖中分別用3種不同的顏色來代表這3種通信方式。一般來說,同一進程內的線程間通信採用的是 Handler消息隊列機制,不同進程間的通信採用的是binder機制,另外與Zygote進程通信採用的Socket。

啓動流程

  1. Process A進程採用Binder IPC向system_server進程發起startService請求;
  2. system_server進程接收到請求後,向zygote進程發送創建進程的請求;
  3. zygote進程fork出新的子進程Remote Service進程;
  4. Remote Service進程,通過Binder IPC向sytem_server進程發起attachApplication請求;
  5. system_server進程在收到請求後,進行一系列準備工作後,再通過binder IPC向remote Service進程發送scheduleCreateService請求;
  6. Remote Service進程的binder線程在收到請求後,通過handler向主線程發送CREATE_SERVICE消息;
  7. 主線程在收到Message後,通過發射機制創建目標Service,並回調Service.onCreate()方法。
    到此,服務便正式啓動完成。當創建的是本地服務或者服務所屬進程已創建時,則無需經過上述步驟2、3,直接創建服務即可。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章