Android中ActivityManagerService與應用程序通信模型分析

今天主要分析下ActivityManagerService(服務端) 與應用程序(客戶端)之間的通信模型,在介紹這個通信模型的基礎上,再

   簡單介紹實現這個模型所需要數據類型。

 

        本文所介紹內容基於android2.2版本。由於android版本的不同,本文所包含的一些類可能在命名等細節上做了一些更改,但

   萬變不離其宗,整個核心思想和通信流程依舊如下。

            例如,①、在android2.3上就將android2.2中ActivityManagerService的很處理邏輯提煉出來,形成了一個單獨的

        ActivityStack類,因而顯得更“高級”;

                     ②、將後文講解到的HistoryRecord.java直接重名名ActivityRecord.java等。

 

             很多不同點我也就不在細說了。大家在研究源碼的過程裏,注意差異就成。

 

 

       Android的三大核心功能有如下三個:

           1、View.java    關於View工作原理,《Android中View繪製流程以及invalidate()等相關方法分析》分析過。

                   功能有: 繪製圖形、處理觸摸、按鍵事件等;

           2、ActivityManagerService.java  簡稱爲 AMS

                   功能有:管理所有應用程序的Activity 、內存管理等 。

           3、WindowManagerService.java 簡稱爲WMS

                   功能有:爲所有應用程序分配窗口,並管理這些窗口。

 

 

        從上可知,AMS作爲一種系統級服務管理所有Activity,當操作某個Activity時,例如: 啓動一個新的Activity、停止當前

    Activity,必須報告給AMS,而不能“擅自處理”。當AMS接受到具體通知時,會根據該通知的類型,首先會更新內部記錄,

    然後在通知相應客戶進程去運行一個新的Activity或者停止指定的Activity。另外,由於AMS記錄了所有Activity的信息,當然

    能夠主動的調度這些Activity,甚至在內存不足時,主動殺死後臺的Activity。

 

    首先對模型中可能運到的類做一個介紹:

     ActivityThread.java    路徑位於:\frameworks\base\core\java\android\app\ActivityThread.java

         說明: 該類爲應用程序(即APK包)所對應進程(一個進程裏可能有多個應用程序)的主線程類,即我們通常所說的UI線程。

           一個ActivityThread類對應於一個進程。最重要的是,每個應用程序的入口是該類中的static main()函數 。

   

      Activity.java               路徑位於:\frameworks\base\core\java\android\app\Activity.java

        說明:該類是與用戶交互的對象,同時也是APK應用程序運行的最小單元。ActivityThread類會根據用戶的操作選擇運行

          哪個Activity。當前運行的Activity是出於resume狀態(有且僅有一個),其他Activity出於pause或stop狀態。

 

      Instrumentation.java  路徑位於 :\frameworks\base\core\java\android\app\ActivityThread.java

         說明: 該類用於具體操作某個Activity的功能----單向(oneway)調用AMS以及統計、測量該應用程序的所有開銷。

            一個Instrumentation類對應於一個進程。每個Activity內部都有一個該Instrumentation對象的引用。

 

      舉個例子吧。

           我們將我們應用程序比作一個四合院,那麼Activity對應於四合院的人,ActivithThread對應於院子的主人----管理所有人,

    Instrumentation對應於管家------受氣的命,接受來自人(Activity/ActivithThread)的命令 ,去單向(oneway)調用AMS 。

 

  ApplicationThread類是ActivityThread的內部類:

       說明:該類是一個Binder類,即可實現跨進程通信。主要用於接受從AMS傳遞過來的消息,繼而做相應處理。

 

   ActivityManagerService.java 路徑位於:        

                                       \frameworks\base\services\java\com\android\server\am\ActivityManagerService.java

       說明:該類是一個Binder類,即可實現跨進程通信。因此可以接受從客戶端,例如Instrumentation、Context等調用過來的

           信息。ActivityManagerService提供了全局的代理對象,供IPC調用。

 

 

  AMS與ActivityThread的通信模型圖如下:

 

                        

 

 

  從該模型圖我們得知以下知識點:

 

       第一、 引起調用AMS的對象通常有Context 、 Instrumentatio、ActivityThread等 。

       第二、當AMS接受到來自某個應用程序傳來的消息後,在AMS內部處理完畢後,會通過Binder機制回調回該應用程序

             所在ApplicationThread服務端類,即ActivityThread.java類。

       第三、當ActivityThread接受到AMS傳遞過來的消息後,進行內部處理。如果需要的話,會繼續與AMS通信。

       最後,當整個通信完成時,ActivityThread會選擇合適的對象,例如Service、Activity、BroadcastReceiver等去做相應的

            處理。

 

 

 

  最後,對通信模型設計到的設計到的數據類進行介紹:

 

  AMS 服務端用到的數據類:

    ProcessRecord.java  路徑:  \frameworks\base\services\java\com\android\server\am\ ProcessRecord.java

        說明: 記錄每個進程的裏的全部信息 。 主要信息包括該進程中包含的Activity、Provider、Service等信息、進程文件信息、

             該進程的內存狀態信息。

        源代碼(部分)如下: 

[java] view plain copy
 print?
  1. /** 
  2.  * Full information about a particular process that is currently running. 
  3.  */  
  4. class ProcessRecord implements Watchdog.PssRequestor {  
  5.   
  6.     // 第一個應用程序的ApplicationInfo對象  
  7.     final ApplicationInfo info; // all about the first app in the process  
  8.     final String processName; // name of the process 進程名  
  9.     // List of packages running in the process  
  10.     final HashSet<String> pkgList = new HashSet(); // 該進程裏運行的應用程序包名  
  11.     // contains HistoryRecord objects  
  12.     final ArrayList activities = new ArrayList(); // 保存該進程下所有Activity的信息<activty  
  13.                                                     // /> AndroidManifest.xml  
  14.     // all ServiceRecord running in this process  
  15.     final HashSet services = new HashSet(); // 保存該進程下所有Service的信息 <Service />  
  16. }  

  

    HistoryRecord.java   路徑:\frameworks\base\services\java\com\android\server\am\HistoryRecord.java

         說明: 記錄每個Activity的全部信息,因爲AMS不知道客戶端Activity的存在,因此在服務端用HistroyRecord對象來方便

     管理和統計對應客戶端Activity的信息。而且該類也是一個Binder類,因此可以跨進程調用。在客戶端中,ActivityThread同樣

     用HistroyRecord的“代理“ Proxy對象去標記對應的Activity。

           源代碼(部分)如下:

[java] view plain copy
 print?
  1. **  
  2.  * An entry in the history stack, representing an activity.  
  3.  */  
  4. class HistoryRecord extends IApplicationToken.Stub {  
  5.   
  6.     final ActivityInfo info; // all about me     
  7.     final Intent intent; // the original intent that generated us   
  8.     final String shortComponentName; // the short component name of the intent    
  9.     TaskRecord task;        // the task this is in.  該Activity對應Task的信息  
  10.     ProcessRecord app;  // if non-null, hosting application 該Activity所在的進程信息  
  11.       
  12.     boolean stopped;        // is activity pause finished?  該Activity是否已經停止 即onStop();  
  13.     boolean delayedResume;  // not yet resumed because of stopped app switches? 是否需要暫時停止啓動  
  14.     boolean finishing;      // activity in pending finish list?  是否正在finish 即殺死該Activity  
  15.       
  16.     ...  
  17. }  

     TaskRecord.java       路徑:\frameworks\base\services\java\com\android\server\am\TaskRecord.java

         說明: 記錄每個任務 Task的信息。 Activity可以運行在不同的Task中。

           源代碼(部分)如下:

[java] view plain copy
 print?
  1. class TaskRecord {  
  2.     // id   
  3.     final int taskId;       // Unique identifier for this task.  
  4.     final String affinity;  // The affinity name for this task, or null.  
  5.     final boolean clearOnBackground; // As per the original activity.  
  6.     //啓動一個新的Task的的Intent信息  
  7.     Intent intent;          // The original intent that started the task.  
  8.     Intent affinityIntent;  // Intent of affinity-moved activity that started this task.  
  9.     ComponentName origActivity; // The non-alias activity component of the intent.  
  10.     ComponentName realActivity; // The actual activity component that started the task.  
  11.     //運行在該Task的Activity數目  
  12.     int numActivities;      // Current number of activities in this task.  
  13. }  

    ActivityManagerService.java

        PS:該類還是相當龐大的,有着琳琅滿目的數據對象,稍不注意,就給迷失了。

           源代碼(部分)如下:

[java] view plain copy
 print?
  1. class ActivityManagerService extends ActivityManagerNative implements xxx {  
  2.     // This is the maximum number of activities that we would like to have  
  3.     // running at a given time.  
  4.     static final int MAX_ACTIVITIES = 20;  //系統中正在運行的Activity數目,最大爲20  
  5.     // Maximum number of recent tasks that we can remember.  
  6.     static final int MAX_RECENT_TASKS = 20//最大的Task數目爲20      
  7.     /** 
  8.      * The back history of all previous (and possibly still 
  9.      * running) activities.  It contains HistoryRecord objects. 
  10.      */  //當前系統中正在運行的Activity信息,即處於onPause、onStop、onResume狀態的Activity信息  
  11.     final ArrayList mHistory = new ArrayList();    
  12.   
  13.     /** 
  14.      * Current activity that is resumed, or null if there is none. 
  15.      */  
  16.     HistoryRecord mResumedActivity = null;  //當前正在於用戶交互的Activity信息,即處於onResume狀態。  
  17.     /** 
  18.      * When we are in the process of pausing an activity, before starting the 
  19.      * next one, this variable holds the activity that is currently being paused. 
  20.      */  
  21.     HistoryRecord mPausingActivity = null;  //當前正在暫停的Activity信息,即正在onPause();  
  22.     /** 
  23.      * All of the applications we currently have running organized by name. 
  24.      * The keys are strings of the application package name (as 
  25.      * returned by the package manager), and the keys are ApplicationRecord 
  26.      * objects. 
  27.      */  //當前正在運行的Process信息  
  28.     final ProcessMap<ProcessRecord> mProcessNames  = new ProcessMap<ProcessRecord>();  
  29.     //開始啓動一個Activity  
  30.     public final int startActivity(){ ...}  
  31. }  

 

 ActivityThread所在客戶端 :

 

   基本對象都已在開篇介紹過,ActivityThread 、ApplicationThread 類。

     ActivityThread .java 

          源代碼(部分)如下:

[java] view plain copy
 print?
  1. /** 
  2.  * This manages the execution of the main thread in an 
  3.  * application process, scheduling and executing activities, 
  4.  * broadcasts, and other operations on it as the activity 
  5.  * manager requests. 
  6.  * 
  7.  * {@hide} 
  8.  */  
  9. public final class ActivityThread {  
  10.       
  11.      //保存了該進程裏所有正在運行的Activity信息  , 即沒有onDestroy()的Activity  
  12.      //IBinder對象是HistoryRecord的代理對象,在客戶端已IBinder標記每個Activity信息  
  13.      final HashMap<IBinder, ActivityRecord> mActivities = new HashMap<IBinder, ActivityRecord>();  
  14.        
  15.      final H mH = new H();  // H對象 ,Handler子類  
  16.      Instrumentation mInstrumentation;  
  17.      ...  
  18. }  

 

    ApplicationThread    是ActivityThread的內部類

        源代碼(部分)如下:

[java] view plain copy
 print?
  1. public final class ActivityThread {  
  2.     ...   
  3.     //Binder類 主用功能是接受從AMS傳遞過來的消息,做處理後轉發給H類去進一步處理。  
  4.     private final class ApplicationThread extends ApplicationThreadNative{  
  5.          public final void schedulePauseActivity(){...}  
  6.           public final void scheduleSendResult{...}  
  7.           public final void scheduleSendResult(){...}  
  8.     }  
  9. }  


   最後介紹一下ActivityThread的兩個內部類。

 

     H類      是ActivityThread的內部類

       說明 :H類是一個Hander子類 ,該類僅僅是爲了異步調用而設計的,使用方法同Hander類一樣。

           源代碼(部分)如下:

[java] view plain copy
 print?
  1. public final class ActivityThread {   
  2.     ...  
  3.     private final class H extends Handler {  
  4.             
  5.         private H() {  
  6.            SamplingProfiler.getInstance().setEventThread(mLooper.getThread());  
  7.         }  
  8.         //處理消息  
  9.         public void handleMessage(Message msg){  
  10.              switch (msg.what) {  
  11.                case LAUNCH_ACTIVITY: {  
  12.                  //啓動一個Activity  
  13.                  ActivityRecord r = (ActivityRecord)msg.obj;  
  14.                  r.packageInfo = getPackageInfoNoCheck(  
  15.                          r.activityInfo.applicationInfo);  
  16.                  handleLaunchActivity(r, null);                   
  17.                }   
  18.                ...  
  19.              }  
  20.         }  
  21.    }  
  22. }  


 ActivityRecord類同樣是ActivityThread的內部類

       說明:在客戶端保存當前Activity的相關信息,方便ActivityThread管理維護Activity。這個類在實現和功能上對應於AMS的

          HistoryRecord類。

           源代碼(部分)如下:

[java] view plain copy
 print?
  1. <span style="font-size:16px;">public final class ActivityThread{  
  2.     ...  
  3.     //記錄了客戶端Activity的信息  
  4.     private static final class ActivityRecord {  
  5.          IBinder token;  //該變量對應於AMS服務端HistoryRecord對象  
  6.          Intent intent;  //啓動該Activity對應的intent信息  
  7.          Bundle state;   //保存一些信息  onCreate(state)  
  8.          Activity activity;  //對應於Activity類  
  9.          ActivityInfo activityInfo;  //對應的ActivityInfo對象  
  10.          ...  
  11.     }  
  12. }</span>  

      

            另外我再對客戶端Activity、ActivityRecord、ActivityThread 類包含的IBinder token屬性進行一下說明:該token變量

     實際上指向的的ActivityManagerService的HistoryRecord對象,他們是一一對應的。在應用程序內部和AMS都通過該token

     變量來標記我們實際需要的Activity信息。 如下圖所示:

 

                           

 

         對ActivityManagerService通信模型以及數據類有一定認識後,那麼現在你就可以具體去接觸每個操作是怎麼實現的了。 例

  如 startActivity()、 registerReceiver()等。

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