Android中AMS的理解與簡(jiǎn)介

1. AMS功能概述

  • 組件狀態(tài)管理:包括四大組件的開(kāi)啟,關(guān)閉等一系列操作。如startActivity,startActivityAndWait,activityPaused,startService,stopService,removeContentProvider等
  • 組件狀態(tài)查詢:查詢組件當(dāng)前運(yùn)行等情況。如getCallingActivity,getService等
  • Task相關(guān):包括removeTask,removeSubTask,moveTaskBackwards,moveTaskToFront等

AMS是通過(guò)ActivityStack及其他數(shù)據(jù)結(jié)構(gòu)來(lái)記錄,管理系統(tǒng)中的Activity及其他組件狀態(tài)的,并提供查詢功能的一個(gè)系統(tǒng)服務(wù)。

2. AMS7.0和8.0的區(qū)別

  • AMS7.0:

    ActivityManager(AM)是一個(gè)和AMS相關(guān)聯(lián)的類,它主要對(duì)運(yùn)行中的activity進(jìn)行管理,這些管理工作并不是由ActivityManager來(lái)處理的,而是交由AMS來(lái)處理的。ActivityManager中的方法會(huì)通過(guò)ActivityManagerNative(AMN)的getDefault()來(lái)得到ActivityManageProxy(AMP),通過(guò)AMP就可以和AMN進(jìn)行通訊。而AMN是一個(gè)抽象類,它將功能交給它的子類AMS來(lái)處理,因此AMP就是AMS的代理類。AMS作為系統(tǒng)服務(wù),很多服務(wù)是不會(huì)暴露給AM的。

    AMS的啟動(dòng)過(guò)程會(huì)調(diào)用Instrumentation.execStartActivities():

           public void execStartActivities(Context who, IBinder contextThread,
                   IBinder token, Activity target, Intent[] intents, Bundle options) {
               execStartActivitiesAsUser(who, contextThread, token, target, intents, options,
                       UserHandle.myUserId());
           }
    

    這里調(diào)用execStartActivitiesAsUser():

           public void execStartActivitiesAsUser() {
                   int result = ActivityManagerNative.getDefault()
                       .startActivities();
           }
        
    

    通過(guò)ActivityManagerNative.getDefault()獲取AMP,那么看一下getDefault():

           private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
               protected IActivityManager create() {
                   //通過(guò)ServiceManager獲取AMS代理對(duì)象
                   IBinder b = ServiceManager.getService("activity");
                   IActivityManager am = asInterface(b);
                   return am;
               }
           };
    

    這里首先通過(guò)ServiceManager獲取了AMS的代理對(duì)象,然后調(diào)用了asInterface():

           static public IActivityManager asInterface(IBinder obj) {
               return new ActivityManagerProxy(obj);
           }
    

    可以看到在asInterface里,構(gòu)造了一個(gè)ActivityManagerProxy,并傳入了AMS代理對(duì)象的引用,那么AMP就持有了具有進(jìn)程間通訊能力的AMS代理對(duì)象,那么它也就具備了進(jìn)程間通訊的能力。那么繼續(xù)看它的startActivities():

           public int startActivity() {
               mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
               reply.readException();
               return result;
           }
    

    這里調(diào)用了mRemote.transact(),這個(gè)mRemote就是傳進(jìn)來(lái)的AMS代理對(duì)象。調(diào)用它的方法實(shí)際就是進(jìn)程間通訊,這時(shí)進(jìn)程就會(huì)切換到AMS所在的SystemServer進(jìn)程。mRemote.transact()經(jīng)過(guò)一系列處理,最終回調(diào)到AMS到onTransact():

           public boolean onTransact(){
               switch (code) {
               case START_ACTIVITY_TRANSACTION:
               {
                      //這里其實(shí)是在父類AMN中,AMS重寫了并調(diào)用了onTransact(),最后調(diào)用AMS的startActivity()
                   int result = startActivity(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
                   return true;
               }
             }
    
  • AMS8.0:直接采用了AIDL進(jìn)行通訊

    AMS8.0的啟動(dòng)過(guò)程同樣是Instrumentation.execStartActivities():

           public void execStartActivities() {
               execStartActivitiesAsUser();
           }
    

    再看execStartActivitiesAsUser():

           public void execStartActivitiesAsUser() {
                   int result = ActivityManager.getService()
                       .startActivities();
           }
    

    可以看到,這里和7.0的區(qū)別是這里調(diào)用了ActivityManager.getService()

           public static IActivityManager getService() {
               return IActivityManagerSingleton.get();
           }
           private static final Singleton<IActivityManager> IActivityManagerSingleton =
                   new Singleton<IActivityManager>() {
                       @Override
                       protected IActivityManager create() {
                           final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                          //返回一個(gè)代理對(duì)象。
                           final IActivityManager am = IActivityManager.Stub.asInterface(b);
                           return am;
                       }
                   };
    

    可以看到,這里直接返回了一個(gè)AMS代理對(duì)象,沒(méi)有了AMP。

3. AMS的啟動(dòng)過(guò)程

Android系統(tǒng)啟動(dòng)過(guò)程簡(jiǎn)述中可知,AMS在SystemServer的main()中啟動(dòng)??创a:

       public static void main(String[] args) {
           new SystemServer().run();
       }

再看run():

       private void run() {
                             //創(chuàng)建消息Looper
               Looper.prepareMainLooper();
                             //加載動(dòng)態(tài)庫(kù)
               System.loadLibrary("android_servers");
     
               //創(chuàng)建系統(tǒng)Context
               createSystemContext();
   
               //創(chuàng)建SystemManager
               mSystemServiceManager = new SystemServiceManager(mSystemContext);
                             //啟動(dòng)引導(dǎo)服務(wù)
               startBootstrapServices();
                     //啟動(dòng)核心服務(wù)
               startCoreServices();
                     //啟動(dòng)其他服務(wù)
               startOtherServices();
                     //開(kāi)啟消息循環(huán)
               Looper.loop();
           throw new RuntimeException("Main thread loop unexpectedly exited");
       }

可以看到,這里創(chuàng)建了SystemManager,然后在startBootstrapServices()中用SystemManager創(chuàng)建了AMS,看代碼:

       private void startBootstrapServices() {
             //創(chuàng)建AMS
           mActivityManagerService = mSystemServiceManager.startService(
                   ActivityManagerService.Lifecycle.class).getService();
}

可以看到這里調(diào)用了SystemManager.startService(),并傳入了ActivityManagerService.Lifecycle來(lái)創(chuàng)建AMS,看代碼:

       public <T extends SystemService> T startService(Class<T> serviceClass) {
                              //通過(guò)反射的方式創(chuàng)建service,并調(diào)用了構(gòu)造方法
               Constructor<T> constructor = serviceClass.getConstructor(Context.class);
               service = constructor.newInstance(mContext);
                           //調(diào)用startService
               startService(service);
               return service;
       }

這里首先通過(guò)反射的方式創(chuàng)建了service,并調(diào)用了它的構(gòu)造,最后調(diào)用()。startService0這個(gè)serviceClass是傳進(jìn)來(lái)的ActivityManagerService.Lifecycle,看一下這個(gè)類:

       public static final class Lifecycle extends SystemService {
           private final ActivityManagerService mService;
                
           public Lifecycle(Context context) {
               super(context);
                 //在構(gòu)造里創(chuàng)建AMS
               mService = new ActivityManagerService(context);
           }
   
           @Override
           public void onStart() {
                 //調(diào)用AMS的start()
               mService.start();
           }
                 //返回AMS
           public ActivityManagerService getService() {
               return mService;
           }
       }

可以看到構(gòu)造里構(gòu)造了AMS。那么再看上一步的startService()

       public void startService(@NonNull final SystemService service) {
           //將創(chuàng)建的service保存到ArrayList類型的mServices中,完成注冊(cè)
           mServices.add(service);
             //調(diào)用ActivityManagerService.Lifecycle的onStart()
           service.onStart();
      }

這里傳入的service就是AMS,將它保存到ArrayList類型的mServices中完成注冊(cè),最后調(diào)用了service.onStart(),從上一步可知,最后調(diào)用的是AMS的start()。同樣從上一步可知getService()也返回的是構(gòu)造的AMS。

那么到這里AMS就啟動(dòng)并且返回了。

4. AMS與應(yīng)用程序進(jìn)程

  • 啟動(dòng)應(yīng)用程序進(jìn)程時(shí)AMS會(huì)通過(guò)進(jìn)程名和uid查詢這個(gè)進(jìn)程是否存在
  • 如果應(yīng)用程序進(jìn)程不存在,則AMS就會(huì)請(qǐng)求Zygote進(jìn)程創(chuàng)建需要的應(yīng)用程序進(jìn)程

5. AMS中重要的數(shù)據(jù)結(jié)構(gòu)

  • ActivityRecord:記錄了Activity的所有信息,因此它用來(lái)描述一個(gè)activity。它是在activity啟動(dòng)時(shí)被創(chuàng)建的,具體是在ActivityStarter的startActivity()中被創(chuàng)建的。它存儲(chǔ)的信息主要包括以下內(nèi)容:
    • service:AMS的引用
    • info:ActivityInfo,Activity中代碼和AndroidManifest設(shè)置的節(jié)點(diǎn)信息,如launchMode
    • launcherFromPackage:啟動(dòng)activity的包名
    • taskAffinity:activity希望歸屬的棧
    • task:TaskRecord,Activity所在的TaskRecord
    • app:ProcessRecord,ActivityRecord所在的應(yīng)用程序進(jìn)程
    • state:ActivityState,當(dāng)前activity的狀態(tài)
    • icon:Activity的圖標(biāo)資源和標(biāo)致符
    • theme:Activity的主題資源標(biāo)識(shí)符
  • TaskRecord:用來(lái)描述一個(gè)Activity任務(wù)棧
    • taskId:任務(wù)棧的唯一標(biāo)識(shí)符
    • affinity:任務(wù)棧的傾向性
    • Intent:啟動(dòng)這個(gè)activity的intent
    • mActivites:ArrayList<ActivityRecord>,按照歷史順序排列的Activity記錄
    • mStack:ActivityStack,當(dāng)前歸屬的ActivityStack
    • mService:AMS的引用
  • ActivityStack:用來(lái)管理系統(tǒng)所有的Activity,內(nèi)部維護(hù)了Activity的所有狀態(tài),特殊狀態(tài)的Activity以及和Activity相關(guān)的列表等數(shù)據(jù)。

6. Activity棧管理

Activity是放入Activity任務(wù)棧中的,有了任務(wù)棧,系統(tǒng)和開(kāi)發(fā)者就能更好地應(yīng)用和管理Activity,來(lái)完成各種業(yè)務(wù)邏輯

  • Activity任務(wù)棧模型

    Activity任務(wù)棧由多種數(shù)據(jù)結(jié)構(gòu)共同組合而成。其中ActivityRecord用來(lái)記錄一個(gè)Activity的所有信息。一個(gè)TaskRecord包含了一個(gè)或多個(gè)ActivityRecord,TaskRecord用來(lái)表示Activity的任務(wù)棧。ActivityStack又包含了一個(gè)或者多個(gè)TaskRecord,它是TaskRecord的管理者。Activity棧管理是建立在Activity棧模型之上的,有了棧管理,就可以對(duì)應(yīng)用程序進(jìn)行操作,應(yīng)用程序可以復(fù)用自身應(yīng)用中以及其他應(yīng)用的Activity,節(jié)省資源。

  • Launch Mode:用于設(shè)置Activity的啟動(dòng)方式,無(wú)論是哪種啟動(dòng)方式,所啟動(dòng)的Activity都會(huì)位于Activity的棧頂,主要有4種模式:

    • standerd:默認(rèn)模式,每次啟動(dòng)Activity都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例
    • singleTop:如果要啟動(dòng)的Activity已經(jīng)在棧頂,則不會(huì)重新創(chuàng)建Activity,同時(shí)該Activity的onNewIntent()會(huì)被調(diào)用。如果要啟動(dòng)的Activity不在棧頂,則會(huì)重新創(chuàng)建該Activity實(shí)例
    • singleTask:如果要啟動(dòng)的Activity已經(jīng)存在與它想要?dú)w屬的棧中,那么不會(huì)創(chuàng)建該Activity的實(shí)例,會(huì)將棧中所有該Activity上的Activity出棧,同時(shí)該Activity的onNewIntent()被調(diào)用。如果要啟動(dòng)的Activity不存在于它想要?dú)w屬的棧中,并且該棧存在,則會(huì)創(chuàng)建該Activity實(shí)例入棧。如果要啟動(dòng)的Activity想要?dú)w屬的棧不存在,則新創(chuàng)建一個(gè)新棧,然后創(chuàng)建該Activity并入棧。
    • singleInstance:和singeTask基本類似,不同的是啟動(dòng)Activity時(shí),首先要?jiǎng)?chuàng)建一個(gè)新棧,然后創(chuàng)建該Activity實(shí)例并入棧,新棧只會(huì)存在該Activity一個(gè)實(shí)例。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容