AMS分析 -- 啟動過程


 

一. AMS簡介

   AmS可以說是Android上層系統最核心的模塊之一,其主要完成管理應用進程的生命周期以及進程的Activity,Service,Broadcast和Provider等。

   從系統運行的角度看,AmS可以分為Client端和Service端:

             Client端運行在各個app進程,app進程實現了具體的 Activity,Service等,告訴系統我有那些Activity,Service等,並且調用系統接口來完成顯示;

             Service端運行在 SystemServer進程,是系統級別的ActivityManagerService的具體實現,其響應Client端的系統調用請求,並且管理 Client端各個app進程的生命周期。

   

                                                         圖1 AmS基本類圖

 

    關於AMS的代理模式可以參考 http://www.cnblogs.com/neo-java/p/7230042.html

 

 

     如下圖是AmS內部主要數據結構類圖,看了code相信大家都會知道這些類都是干什么的,這兒只是總結一下。

  

                                                           圖2  AmS內部主要數據結構類圖

 

 

二. AMS啟動過程

 啟動過程主要分為四部分:

1、創建出SystemServer進程的Android運行環境。
在這一部分,SystemServer進程主要創建出對應的ActivityThread和ContextImpl,構成Android運行環境。
AMS的后續工作依賴於SystemServer在此創建出的運行環境。

2、完成AMS的初始化和啟動。
在這一部分,單純地調用AMS的構造函數和start函數,完成AMS的一些初始化工作。

3、將SystemServer進程納入到AMS的管理體系中。
AMS作為Java世界的進程管理和調度中心,要對所有Java進程一視同仁,因此SystemServer進程也必須被AMS管理。
在這個過程中,AMS加載了SystemServer中framework-res.apk的信息,並啟動和注冊了SettingsProvider.apk。

4、開始執行AMS啟動完畢后才能進行的工作。
系統中的一些服務和進程,必須等待AMS完成啟動后,才能展開后續工作。
在這一部分,AMS通過調用systemReady函數,通知系統中的其它服務和進程,可以進行對應工作了。
在這個過程中,值得我們關注的是:Home Activity被啟動了。當該Activity被加載完成后,最終會觸發ACTION_BOOT_COMPLETED廣播。

下面分別講解。

 

 2.1 創建SystemServer進程的Android運行環境 

 

2.1.1  我們已經知道了,zygote創建出的第一個java進程是SystemServer。
          在SystemServer的run函數中,在啟動AMS之前,調用了createSystemContext函數。

其代碼如下所示:

 1 .............
 2 //SystemServer在啟動任何服務之前,就調用了createSystemContext
 3 //創建出的Context保存在mSystemContext中
 4 // Initialize the system context.
 5 createSystemContext();
 6 
 7 // Create the system service manager.
 8 //SystemServiceManager負責啟動所有的系統服務,使用的Context就是mSystemContext
 9 mSystemServiceManager = new SystemServiceManager(mSystemContext);
10 .............

 

我們跟進一下createSystemContext:

 1 private void createSystemContext() {
 2     //調用ActivityThread的systemMain函數,其中會創建出系統對應的Context對象
 3     ActivityThread activityThread = ActivityThread.systemMain();
 4 
 5     //取出上面函數創建的Context對象,保存在mSystemContext中
 6     mSystemContext = activityThread.getSystemContext();
 7 
 8     //設置系統主題
 9     mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
10 }

以上函數中,最重要的就是ActivityThread.systemMain了,我們分析一下該函數。

 

2.1.2 ActivityThread.systemMain的代碼如下

 1 public static ActivityThread systemMain() {
 2     // The system process on low-memory devices do not get to use hardware
 3     // accelerated drawing, since this can add too much overhead to the
 4     // process.
 5     if (!ActivityManager.isHighEndGfx()) {
 6         //雖然寫着ActivityManager,但和AMS沒有任何關系
 7         //就是利用系統屬性和配置信息進行判斷
 8 
 9         //關閉硬件渲染功能
10         ThreadedRenderer.disable(true);
11     } else {
12         ThreadedRenderer.enableForegroundTrimming();
13     }
14 
15     //創建ActivityThread
16     ActivityThread thread = new ActivityThread();
17     //調用attach函數,參數為true
18     thread.attach(true);
19     return thread;
20 }

從上面的代碼可以看出,ActivityThread的systemMain函數中,除了進行是否開啟硬件渲染的判斷外,主要作用是:
創建出ActivityThread對象,然后調用該對象的attach函數。

 

ActivityThread的構造函數比較簡單:

1 ActivityThread() {
2     mResourcesManager = ResourcesManager.getInstance();
3 }

 

比較關鍵的是它的成員變量:

 1 ..........
 2 //定義了AMS與應用通信的接口
 3 final ApplicationThread mAppThread = new ApplicationThread();
 4 
 5 //擁有自己的looper,說明ActivityThread確實可以代表事件處理線程
 6 final Looper mLooper = Looper.myLooper();
 7 
 8 //H繼承Handler,ActivityThread中大量事件處理依賴此Handler
 9 final H mH = new H();
10 
11 //用於保存該進程的ActivityRecord
12 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>()
13 ..........
14 //用於保存進程中的Service
15 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
16 ...........
17 //用於保存進程中的Application
18 final ArrayList<Application> mAllApplications = new ArrayList<Application>();
19 ...........

我們需要知道的是,ActivityThread是android Framework中一個非常重要的類,它代表一個應用進程的主線程,其職責就是調度及執行在該線程中運行的四大組件。
在Android中,應用進程指那些運行APK的進程,它們由zygote fork出來,其中運行着獨立的dalvik虛擬機。
與應用進程相對的就是系統進程,例如zygote和SystemServer。

 注意到此處的ActivityThread創建於SystemServer進程中。
由於SystemServer中也運行着一些系統APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以認為SystemServer是一個特殊的應用進程。

對於上面提到的ActivityThread的成員變量,其用途基本上可以從名稱中得知,這里僅說明一下ApplicationThread。

 

AMS負責管理和調度進程,因此AMS需要通過Binder機制和應用進程通信。
為此,Android提供了一個IApplicationThread接口,該接口定義了AMS和應用進程之間的交互函數。

如上圖所示,ActivityThread作為應用進程的主線程代表,在其中持有ApplicationThread。ApplicationThread繼承ApplicationThreadNative。
當AMS與應用進程通信時,ApplicationThread將作為Binder通信的服務端。

 AMS與應用進程通信時,通過ApplicationThreadNative獲取應用進程對應的ApplicationThreadProxy對象。
通過ApplicationThreadProxy對象,將調用信息通過Binder傳遞到ActivityThread中的ApplicationThread。
這個調用過程,今后還會遇到,碰到的時候再詳細分析。

 

2.1.3 ActivityThread.attach

 1 我們看看ActivityThread的attach函數:
 2 
 3 //此時,我們傳入的參數為true,表示該ActivityThread是系統進程的ActivityThread
 4 private void attach(boolean system) {
 5     //創建出的ActivityThread保存在類的靜態變量sCurrentActivityThread
 6     //AMS中的大量操作將會依賴於這個ActivityThread
 7     sCurrentActivityThread = this;
 8     mSystemThread = system;
 9 
10     if (!system) {
11         //應用進程的處理流程
12         ..........
13     } else { 
14         //系統進程的處理流程,該情況只在SystemServer中處理
15 
16         // Don't set application object here -- if the system crashes,
17         // we can't display an alert, we just want to die die die.
18         //設置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer進程的名稱為“system_process”
19         android.ddm.DdmHandleAppName.setAppName("system_process",
20                 UserHandle.myUserId());
21 
22         try {
23             //創建ActivityThread中的重要成員:Instrumentation、Application和Context
24             mInstrumentation = new Instrumentation();
25             ContextImpl context = ContextImpl.createAppContext(
26                         this, getSystemContext().mPackageInfo);
27             mInitialApplication = context.mPackageInfo.makeApplication(true, null);
28             mInitialApplication.onCreate();
29         } catch (Exception e) {
30             throw new RuntimeException(
31                     "Unable to instantiate Application():" + e.toString(), e);
32         }
33     }
34 
35     //以下系統進程和非系統進程均會執行
36     ................
37     //注冊Configuration變化的回調通知
38     ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
39         @Override
40         public void onConfigurationChanged(Configuration newConfig) {
41             //當系統配置發生變化時(例如系統語言發生變化),回調該接口
42             ...............
43         }
44         .............
45     });
46 }

從上面的代碼可以看出,對於系統進程而言,ActivityThread的attach函數最重要的工作就是創建了Instrumentation、Application和Context。

 

 Instrumentation
Instrumentation是Android中的一個工具類,當該類被啟用時,它將優先於應用中其它的類被初始化。
此時,系統先創建它,再通過它創建其它組件。

此外,系統和應用組件之間的交互也將通過Instrumentation來傳遞。
因此,Instrumentation就能監控系統和組件的交互情況了。

實際使用時,可以創建該類的派生類進行相應的操作。
這個類在介紹啟動Activity的過程時還會碰到,此處不作展開。

 

 Context
Context是Android中的一個抽象類,用於維護應用運行環境的全局信息。
通過Context可以訪問應用的資源和類,甚至進行系統級的操作,例如啟動Activity、發送廣播等。

ActivityThread的attach函數中,通過下面的代碼創建出系統應用對應的Context:

1 .......
2 //ContextImpl是Context的實現類
3 ContextImpl context = ContextImpl.createAppContext(
4         this, getSystemContext().mPackageInfo);
5 .......

 

Application
Android中Application類用於保存應用的全局狀態。

我們經常使用的Activity和Service均必須和具體的Application綁定在一起。
通過上圖的繼承關系,每個具體的Activity和Service均被加入到Android運行環境中。

 

在ActivityThread中,針對系統進程,通過下面的代碼創建了初始的Application:

1 ..............
2 //調用LoadedApk的makeApplication函數
3 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
4 
5 //啟動Application
6 mInitialApplication.onCreate();
7 .............. 

 

我們看一下LoadedApk.makeApplication:

 1 public Application makeApplication(boolean forceDefaultAppClass,
 2         Instrumentation instrumentation) {
 3     if (mApplication != null) {
 4         return mApplication;
 5     }
 6     .............
 7     Application app = null;
 8 
 9     String appClass = mApplicationInfo.className;
10     if (forceDefaultAppClass || (appClass == null)) {
11         //系統進程中,對應下面的appClass
12         appClass = "android.app.Application";
13     }
14 
15     try {
16         java.lang.ClassLoader cl = getClassLoader();
17         if (!mPackageName.equals("android")) {
18             ............
19         }
20 
21         ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
22         //實際上最后通過反射創建出Application
23         app = mActivityThread.mInstrumentation.newApplication(
24                 cl, appClass, appContext);
25         appContext.setOuterContext(app);
26     } catch (Exception e) {
27         ..........
28     }
29 
30     //一個進程支持多個Application,mAllApplications用於保存該進程中的Application對象
31     mActivityThread.mAllApplications.add(app);
32     mApplication = app;
33 
34     ..............
35 }

從上面的代碼不難看出,這部分主要是創建framework-res.apk對應的Application,然后調用它的onCreate函數,完成啟動。

 

第一步的總結
至此,createSystemContext函數介紹完畢。

 

當SystemServer調用createSystemContext完畢后:
1、得到了一個ActivityThread對象,它代表當前進程 (此時為系統進程) 的主線程;
2、得到了一個Context對象,對於SystemServer而言,它包含的Application運行環境與framework-res.apk有關。

 

在繼續分析AMS之前,我們先停下來思考一下,為什么在啟動所有的服務前,SystemServer先要調用createSystemContext?

 個人覺得《深入理解Android》對這個問題,解釋的比較好,大致意思如下:
Android努力構築了一個自己的運行環境。
在這個環境中,進程的概念被模糊化了。組件的運行及它們之間的交互均在該環境中實現。

 createSystemContext函數就是為SystemServer進程搭建一個和應用進程一樣的Android運行環境。

Android運行環境是構建在進程之上的,應用程序一般只和Android運行環境交互。
基於同樣的道理,SystemServer進程希望它內部運行的應用,
也通過Android運行環境交互,因此才調用了createSystemContext函數。

 

創建Android運行環境時,
由於SystemServer的特殊性,調用了ActivityThread.systemMain函數;
對於普通的應用程序,將在自己的主線程中調用ActivityThread.main函數。

上圖表示了進程的Android運行環境涉及的主要類之間的關系。
其中的核心類是ContextImpl,通過它可以得到ContentResolver、系統資源、應用信息等。

 

 2.2 AMS的初始化和啟動

創建完Android運行環境后,SystemServer調用startBootstrapServices,其中就創建並啟動了AMS:

 1 private void startBootstrapServices() {
 2     Installer installer = mSystemServiceManager.startService(Installer.class);
 3 
 4     // Activity manager runs the show.
 5     //啟動AMS,然后獲取AMS保存到變量中
 6     mActivityManagerService = mSystemServiceManager.startService(
 7             ActivityManagerService.Lifecycle.class).getService();
 8 
 9     //以下均是將變量存儲到AMS中
10     mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
11     mActivityManagerService.setInstaller(installer);
12     ..........
13 }

注意到上面的代碼並沒有直接啟動AMS,而是啟動AMS的內部類Lifecycle。
這是迫不得已的做法,由於AMS並沒有繼承SystemService,因此不能通過SystemServiceManager的startService直接啟動它。
可以這樣理解:內部類Lifecycle對於AMS而言,就像一個適配器一樣,讓AMS能夠像SystemService一樣被SystemServiceManager通過反射的方式啟動。

 

 1 public static final class Lifecycle extends SystemService {
 2     private final ActivityManagerService mService;
 3 
 4     public Lifecycle(Context context) {
 5         //Lifecycle由SystemServiceManager啟動,傳入的context就是SystemServer創建出的SystemContext
 6         super(context);
 7 
 8         //1、調用AMS的構造函數
 9         mService = new ActivityManagerService(context);
10      }
11 
12     @Override
13     public void onStart() {
14         //2、調用AMS的start函數
15         mService.start();
16     }
17 
18     public ActivityManagerService getService() {
19         return mService;
20     }
21 }

接下來我們分別看看AMS的構造函數和start函數。

 

AMS的構造函數

  1 public ActivityManagerService(Context systemContext) {
  2     //AMS的運行上下文與SystemServer一致
  3     mContext = systemContext;
  4     ............
  5     //取出的是ActivityThread的靜態變量sCurrentActivityThread
  6     //這意味着mSystemThread與SystemServer中的ActivityThread一致
  7     mSystemThread = ActivityThread.currentActivityThread();
  8     ............
  9     mHandlerThread = new ServiceThread(TAG,
 10             android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
 11     mHandlerThread.start();
 12     //處理AMS中消息的主力
 13     mHandler = new MainHandler(mHandlerThread.getLooper());
 14 
 15     //UiHandler對應於Android中的UiThread
 16     mUiHandler = new UiHandler();
 17 
 18     if (sKillHandler == null) {
 19         sKillThread = new ServiceThread(TAG + ":kill",
 20                 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
 21         sKillThread.start();
 22         //用於接收消息,殺死進程
 23         sKillHandler = new KillHandler(sKillThread.getLooper());
 24     }
 25 
 26     //創建兩個BroadcastQueue,前台的超時時間為10s,后台的超時時間為60s
 27     mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
 28             "foreground", BROADCAST_FG_TIMEOUT, false);
 29     mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
 30             "background", BROADCAST_BG_TIMEOUT, true);
 31     mBroadcastQueues[0] = mFgBroadcastQueue;
 32     mBroadcastQueues[1] = mBgBroadcastQueue;
 33 
 34     //創建變量,用於存儲信息
 35     mServices = new ActiveServices(this);
 36     mProviderMap = new ProviderMap(this);
 37     mAppErrors = new AppErrors(mContext, this);
 38 
 39     //這一部分,分析BatteryStatsService時提過,進行BSS的初始化
 40     File dataDir = Environment.getDataDirectory();
 41     File systemDir = new File(dataDir, "system");
 42     systemDir.mkdirs();
 43     mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
 44     mBatteryStatsService.getActiveStatistics().readLocked();
 45     mBatteryStatsService.scheduleWriteToDisk();
 46     mOnBattery = DEBUG_POWER ? true
 47             : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
 48     mBatteryStatsService.getActiveStatistics().setCallback(this);
 49 
 50     //創建ProcessStatsService,感覺用於記錄進程運行時的統計信息,例如內存使用情況,寫入/proc/stat文件
 51     mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
 52 
 53     //啟動Android的權限檢查服務,並注冊對應的回調接口
 54     mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
 55     mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
 56             new IAppOpsCallback.Stub() {
 57                 @Override public void opChanged(int op, int uid, String packageName) {
 58                     if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
 59                         if (mAppOpsService.checkOperation(op, uid, packageName)
 60                                 != AppOpsManager.MODE_ALLOWED) {
 61                             runInBackgroundDisabled(uid);
 62                         }
 63                     }
 64                 }
 65             });
 66 
 67     //用於定義ContentProvider訪問指定Uri對應數據的權限,aosp中似乎沒有這文件
 68     mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
 69 
 70     //創建多用戶管理器
 71     mUserController = new UserController(this);
 72 
 73     //獲取OpenGL版本
 74     GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
 75             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
 76     ............
 77     //資源配置信息置為默認值
 78     mConfiguration.setToDefaults();
 79     mConfiguration.setLocales(LocaleList.getDefault());
 80     mConfigurationSeq = mConfiguration.seq = 1;
 81 
 82     //感覺用於記錄進程的CPU使用情況
 83     mProcessCpuTracker.init();
 84 
 85     //解析/data/system/packages-compat.xml文件,該文件用於存儲那些需要考慮屏幕尺寸的APK的一些信息
 86     //當APK所運行的設備不滿足要求時,AMS會根據xml設置的參數以采用屏幕兼容的方式運行該APK
 87     mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
 88 
 89     //用於根據規則過濾一些Intent
 90     mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
 91 
 92     //以下的類,似乎用於管理和監控AMS維護的Activity Task信息
 93     //ActivityStackSupervisor是AMS中用來管理Activity啟動和調度的核心類
 94     mStackSupervisor = new ActivityStackSupervisor(this);
 95     mActivityStarter = new ActivityStarter(this, mStackSupervisor);
 96     mRecentTasks = new RecentTasks(this, mStackSupervisor);
 97 
 98     //創建線程用於統計進程的CPU使用情況
 99     mProcessCpuThread = new Thread("CpuTracker") {
100         @Override
101         public void run() {
102             while (true) {
103                 try {
104                     try {
105                         //計算更新信息的等待間隔
106                         //同時利用wait等待計算出的間隔時間
107                         ......
108                     } catch(InterruptedException e) {
109                     }
110                     //更新CPU運行統計信息
111                     updateCpuStatsNow();
112                 } catch (Exception e) {
113                     ..........
114                 }
115             }
116         }
117     };
118 
119     //加入Watchdog的監控
120     Watchdog.getInstance().addMonitor(this);
121     Watchdog.getInstance().addThread(mHandler);
122 }
View Code

從代碼來看,AMS的構造函數還是相對比較簡單的,主要工作就是初始化一些變量。
大多數變量的用途,從命名上基本可以推測出來,實際的使用情況必須結合具體的場景才能進一步了解。

 

AMS的start函數

 1 private void start() {
 2     //完成統計前的復位工作
 3     Process.removeAllProcessGroups();
 4 
 5     //開始監控進程的CPU使用情況
 6     mProcessCpuThread.start();
 7 
 8     //注冊服務
 9     mBatteryStatsService.publish(mContext);
10     mAppOpsService.publish(mContext);
11     Slog.d("AppOps", "AppOpsService published");
12     LocalServices.addService(ActivityManagerInternal.class, new LocalService());
13 }

AMS的start函數比較簡單,主要是:
1、啟動CPU監控線程。該線程將會開始統計不同進程使用CPU的情況。
2、發布一些服務,如BatteryStatsService、AppOpsService(權限管理相關)和本地實現的繼承ActivityManagerInternal的服務。

 

至此AMS初始化相關的內容基本結束,從這些代碼可以看出AMS涉及的類比較多,我們目前無法一一詳述每個類的具體用途。
有機會遇到具體的場景時,再深入分析,此處有個大致印象即可。

 

2.3 將SystemServer納入AMS的管理體系

 

2.3.1 setSystemProcess

AMS完成啟動后,在SystemServer的startBootstrapServices函數中,
下一個與AMS相關的重要調用就是AMS.setSystemProcess了:

1 private void startBootstrapServices() {
2     ...........
3     // Set up the Application instance for the system process and get started.
4     mActivityManagerService.setSystemProcess();
5     ...........
6 }

 

我們跟進一下setSystemProcess函數:

 1 public void setSystemProcess() {
 2     try {
 3         //以下是向ServiceManager注冊幾個服務
 4 
 5         //AMS自己
 6         ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
 7 
 8         //注冊進程統計信息的服務
 9         ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
10 
11         //用於打印內存信息用的
12         ServiceManager.addService("meminfo", new MemBinder(this));
13 
14         //用於輸出進程使用硬件渲染方面的信息
15         ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
16 
17         //用於輸出數據庫相關的信息
18         ServiceManager.addService("dbinfo", new DbBinder(this));
19 
20         //MONITOR_CPU_USAGE默認為true
21         if (MONITOR_CPU_USAGE) {
22             //用於輸出進程的CPU使用情況
23             ServiceManager.addService("cpuinfo", new CpuBinder(this));
24         }
25 
26         //注冊權限管理服務
27         ServiceManager.addService("permission", new PermissionController(this));
28 
29         //注冊獲取進程信息的服務
30         ServiceManager.addService("processinfo", new ProcessInfoService(this));
31 
32         //1、向PKMS查詢package名為“android”的應用的ApplicationInfo
33         ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
34                 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
35 
36         //2、調用installSystemApplicationInfo
37         mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
38 
39         //3、以下與AMS的進程管理有關
40         synchronized (this) {
41             ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
42             app.persistent = true;
43             app.pid = MY_PID;
44             app.maxAdj = ProcessList.SYSTEM_ADJ;
45             app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
46             synchronized (mPidsSelfLocked) {
47                 mPidsSelfLocked.put(app.pid, app);
48             }
49             updateLruProcessLocked(app, false, null);
50             updateOomAdjLocked();
51         }
52     } catch (PackageManager.NameNotFoundException e) {
53         throw new RuntimeException(
54                 "Unable to find android system package", e);
55     }
56 }

 從上面的代碼可以看出,AMS的setSystemProcess主要有四個主要的功能:

  • 1、注冊一些服務;
  • 2、獲取package名為“android”的應用的ApplicationInfo;
  • 3、調用ActivityThread的installSystemApplicationInfo;
  • 4、AMS進程管理相關的操作。

 這四個主要的功能中,第一個比較簡單,就是用Binder通信完成注冊。
我們主要看看后三個功能對應的流程。

 

功能二,獲取ApplicationInfo


如前所述,這部分相關的代碼為:

1 ..........
2 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
3         "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
4 ..........

我們先看看mContext.getPackageManager()的操作過程。

 我們已經知道mContext的實現類是ContextImpl,其中對應的代碼如下:

 1 @Override
 2 public PackageManager getPackageManager() {
 3     if (mPackageManager != null) {
 4         return mPackageManager;
 5     }
 6 
 7     //依賴於ActivityThread的getPackageManager函數
 8     IPackageManager pm = ActivityThread.getPackageManager();
 9     if (pm != null) {
10         // Doesn't matter if we make more than one instance.
11         //利用PKMS的代理對象,構建ApplicationPackageManager
12         //該類繼承PackageManager
13         return (mPackageManager = new ApplicationPackageManager(this, pm));
14     }
15 
16     return null;
17 }

 

跟進一下ActivityThread中的getPackageManager:

 1 public static IPackageManager getPackageManager() {
 2     if (sPackageManager != null) {
 3         //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
 4         return sPackageManager;
 5     }
 6     //依賴於Binder通信,獲取到PKMS對應的BpBinder
 7     IBinder b = ServiceManager.getService("package");
 8     .....................
 9     //得到PKMS對應的Binder服務代理
10     sPackageManager = IPackageManager.Stub.asInterface(b);
11     ....................
12     return sPackageManager;
13 }

從上面的代碼我們可以看到,AMS獲取PKMS用到了Binder通信。

 

實際上,PKMS由SystemServer創建,與AMS運行在同一個進程,AMS完全可以不經過Context、ActivityThread、Binder來獲取PKMS。

 

根據一些資料,推斷出原生代碼這么做的原因是:
SystemServer進程中的服務,也使用Android運行環境來交互, 保留了組件之間交互接口的統一,為未來的系統保留了可擴展性。

得到PKMS的代理對象后,AMS調用PKMS的getApplicationInfo接口,獲取package名為”android”的ApplicationInfo。

在AMS的setSystemProcess被調用前,PKMS已經啟動了。
之前分析PKMS的博客中,我們已經提到,在PKMS的構造函數中,它將解析手機中所有的AndroidManifest.xml,然后形成各種數據結構以維護應用的信息。

getApplicationInfo就是通過package名,從對應的數據結構中,取出對應的應用信息,這部分內容主要就是查詢數據結構的內容,不作深入分析。

 

功能三,installSystemApplicationInfo
得到framework-res.apk對應的ApplicationInfo后,需要將這部分ApplicationInfo保存到SystemServer對應的ActivityThread中。

這部分對應的代碼為:

1 ..............
2 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
3 ..............

AMS中的mSystemThread就是SystemServer中創建出的ActivityThread。

因此我們跟進一下ActivityThread的installSystemApplicationInfo函數:

 1 public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
 2     synchronized (this) {
 3         //調用SystemServer中創建出的ContextImpl的installSystemApplicationInfo函數
 4         getSystemContext().installSystemApplicationInfo(info, classLoader);
 5 
 6         // give ourselves a default profiler
 7         //創建一個Profiler對象,用於性能統計
 8         mProfiler = new Profiler();
 9     }
10 }

 

繼續跟進ContextImpl的installSystemApplicationInfo函數:

1 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
2     //前面已經提到過mPackageInfo的類型為LoadedApk
3     mPackageInfo.installSystemApplicationInfo(info, classLoader);
4 }

 

 隨着流程進入到LoadedApk:

 1 /**
 2 * Sets application info about the system package.
 3 */
 4 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
 5     //這個接口僅供系統進程調用,故這里斷言一下
 6     assert info.packageName.equals("android");
 7 
 8     mApplicationInfo = info;
 9     mClassLoader = classLoader;
10 }

至此,我們知道了installSystemApplicationInfo的真相就是:
將“android”對應的ApplicationInfo(即framework-res.apk對應的ApplicationInfo),
加入到SystemServer之前調用createSystemContext時,創建出的LoadedApk中。
畢竟SystemServer創建System Context時,PKMS並沒有完成對手機中文件的解析,初始的LoadedApk中並沒有持有有效的ApplicationInfo。

 

在此基礎上,AMS下一步的工作就呼之欲出了。

由於framework-res.apk運行在SystemServer進程中,而AMS是專門用於進程管理和調度的,因此SystemServer進程也應該在AMS中有對應的管理結構。

於是,AMS的下一步工作就是將SystemServer的運行環境和一個進程管理結構對應起來,並進行統一的管理。

 

功能四, AMS進程管理

注意到上面的ContentProvider注冊到AMS后,進行了notifyAll的操作。
舉例來說:進程A需要查詢一個數據庫,需要通過進程B中的某個ContentProvider來實施。
如果B還未啟動,那么AMS就需要先啟動B。在這段時間內,A需要等待B啟動並注冊對應的ContentProvider。
B一旦完成ContentProvider的注冊,就需要告知A退出等待以繼續后續的查詢工作。


setSystemProcess函數中,進程管理相關的代碼為:

 1 .............
 2 synchronized (this) {
 3     //創建進程管理對應的結構ProcessRecord
 4     ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
 5 
 6     //由於此時創建的是SystemServer進程對應ProcessRecord
 7     //因此設定了一些特殊值
 8     app.persistent = true;
 9     app.pid = MY_PID;
10     app.maxAdj = ProcessList.SYSTEM_ADJ;
11 
12     //將SystemServer對應的ApplicationThread保存到ProcessRecord中
13     app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
14 
15     synchronized (mPidsSelfLocked) {
16         //按pid將ProcessRecord保存到mPidsSelfLocked中
17         mPidsSelfLocked.put(app.pid, app);
18     }
19 
20     //updateLruProcessLocked來調整進程在mLruProcess列表的位置
21     //在這個列表中,最近活動過得進程總是位於前列,同時擁有Activity的進程位置總是前於只有Service的進程
22     updateLruProcessLocked(app, false, null);
23 
24     //更新進程對應的oom_adj值(oom_adj將決定進程是否被kill掉)
25     updateOomAdjLocked();
26 }
27 ...............

這里我們僅分析一下創建進程管理結構的函數newProcessRecordLocked。
updateLruProcessLocked和updateOomAdjLocked函數比較復雜,等對AMS有更多的了解后,再做分析。

 

 1 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
 2         boolean isolated, int isolatedUid) {
 3     //進程的名稱
 4     String proc = customProcess != null ? customProcess : info.processName;
 5 
 6     //將用於創建該進程的電源統計項
 7     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
 8 
 9     final int userId = UserHandle.getUserId(info.uid);
10     //isolated此時為false
11     if (isolated) {
12         ..........
13     }
14     //創建出對應的存儲結構
15     final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
16 
17     //判斷進程是否常駐
18     if (!mBooted && !mBooting
19             && userId == UserHandle.USER_SYSTEM
20             && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
21         r.persistent = true;
22     }
23 
24     //按進程名將ProcessRecord存入到AMS的變量mProcessNames中
25     //該變量的類型為ProcessMap<ProcessRecord> 
26     //結合前面的代碼,我們知道AMS有兩種方式可以取到ProcessRecord
27     //一是根據進程名,二是根據進程名稱
28     addProcessNameLocked(r);
29     return r;
30 }

 

跟進一下ProcessRecord的構造函數:

 1 ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
 2         String _processName, int _uid) {
 3     mBatteryStats = _batteryStats; //用於電量統計
 4     info = _info;  //保存ApplicationInfo
 5     ...........
 6     processName = _processName;  //保存進程名
 7 
 8     //一個進程能運行多個Package,pkgList用於保存package名
 9     pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));
10 
11     //以下變量和進程調度優先級有關
12     maxAdj = ProcessList.UNKNOWN_ADJ;
13     curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
14     curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
15 
16     //決定進程是否常駐內存(即使被殺掉,系統也會重啟它)
17     persistent = false;
18 
19     removed = false;
20     lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
21 }

 

總結
至此,我們對AMS的setSystemProcess函數分析告一段落。
從上面的代碼可以看出,在這個函數中除了發布一些服務外,主要是:
將framework-res.apk的信息加入到SystemServer對應的LoadedApk中,同時構建SystemServer進程對應的ProcessRecord,
以將SystemServer進程納入到AMS的管理中。

 

2.3.2  AMS的installSystemProviders


接下來AMS啟動相關的操作,定義於SystemServer的startOtherServices函數中。

1 private void startOtherServices() {
2     ...........
3     mActivityManagerService.installSystemProviders();
4     ...........
5 }

 

我們跟進一下AMS的installSystemProviders函數:

 1 public final void installSystemProviders() {
 2     List<ProviderInfo> providers;
 3     synchronized (this) {
 4         //AMS根據進程名取出SystemServer對應的ProcessRecord
 5         ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
 6 
 7         //1、得到該ProcessRecord對應的ProviderInfo
 8         providers = generateApplicationProvidersLocked(app);
 9 
10         //這里僅處理系統級的Provider
11         if (providers != null) {
12             for (int i=providers.size()-1; i>=0; i--) {
13                 ProviderInfo pi = (ProviderInfo)providers.get(i);
14                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
15                         Slog.w(TAG, "Not installing system proc provider " + pi.name
16                                 + ": not system .apk");
17                         providers.remove(i);
18                     }
19                 }
20             }
21         }
22     }
23 
24     if (providers != null) {
25         //2、安裝Provider
26         mSystemThread.installSystemProviders(providers);
27     }
28 
29     //創建ContentObserver監控Settings數據庫中Secure、System和Global表的變化
30     mCoreSettingsObserver = new CoreSettingsObserver(this);
31 
32     //創建ContentObserver監控Settings數據庫中字體大小的變化
33     mFontScaleSettingObserver = new FontScaleSettingObserver();
34 }

從上面的代碼可以看出,installSystemProviders主要是加載運行在SystemServer進程中的 ContentProvider,即SettingsProvider.apk (定義於frameworks/base/packages/SettingsProvider)。

 

上面有兩個比較重要的函數:
1、generateApplicationProvidersLocked返回一個進程對應的ProviderInfo List。
2、ActivityThread可以看做是進程的Android運行環境,因此它的installSystemProviders表示為對應進程安裝ContentProvider。

 

當SettingsProvider被加載到SystemServer進程中運行后,AMS就注冊了兩個ContentObserver監控SettingsProvider中的字段變化。
AMS監控的字段影響范圍比較廣,例如字體發生變化時,很多應用的顯示界面都需要做出調整。
這也許就是讓AMS來負責監控這些字段的原因。

 

 2.4 AMS的systemReady

接下來,我們看看AMS啟動的最后一部分:systemReady。
該函數在SystemServer中startOtherServices的最后被調用:

 1 private void startOtherServices() {
 2     ............
 3     // We now tell the activity manager it is okay to run third party
 4     // code.  It will call back into us once it has gotten to the state
 5     // where third party code can really run (but before it has actually
 6     // started launching the initial applications), for us to complete our
 7     // initialization.
 8     mActivityManagerService.systemReady(new Runnable() {
 9         ..............
10     });
11 }

我們分段看看AMS中systemReady的處理流程。
此處的分段並沒有實際的意義,只是代碼確實太長了,並且連續性不夠,因此分開描述。

 

階段一

 1 public void systemReady(final Runnable goingCallback) {
 2     synchronized(this) {
 3         ..........
 4         //這一部分主要是調用一些關鍵服務SystemReady相關的函數,
 5         //進行一些等待AMS初始完,才能進行的工作
 6 
 7         // Make sure we have the current profile info, since it is needed for security checks.
 8         mUserController.onSystemReady();
 9 
10         mRecentTasks.onSystemReadyLocked();
11         mAppOpsService.systemReady();
12         mSystemReady = true;
13     }
14 
15     ArrayList<ProcessRecord> procsToKill = null;
16     synchronized(mPidsSelfLocked) {
17         //mPidsSelfLocked中保存當前正在運行的所有進程的信息
18         for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
19             ProcessRecord proc = mPidsSelfLocked.valueAt(i);
20 
21             //在AMS啟動完成前,如果沒有FLAG_PERSISTENT標志的進程已經啟動了,
22             //就將這個進程加入到procsToKill中
23             if (!isAllowedWhileBooting(proc.info)){
24                 if (procsToKill == null) {
25                     procsToKill = new ArrayList<ProcessRecord>();
26                 }
27                 procsToKill.add(proc);
28             }
29         }
30     }
31 
32     synchronized(this) {
33         //利用removeProcessLocked關閉procsToKill中的進程
34         if (procsToKill != null) {
35             for (int i=procsToKill.size()-1; i>=0; i--) {
36                 ProcessRecord proc = procsToKill.get(i);
37                 Slog.i(TAG, "Removing system update proc: " + proc);
38                 removeProcessLocked(proc, true, false, "system update done");
39             }
40         }
41 
42         // Now that we have cleaned up any update processes, we
43         // are ready to start launching real processes and know that
44         // we won't trample on them any more.
45 
46         //至此系統准備完畢
47         mProcessesReady = true;
48     }
49     ............
50     //根據數據庫和資源文件,獲取一些配置參數
51     retrieveSettings();
52 
53     final int currentUserId;
54     synchronized (this) {
55         //得到當前的用戶ID
56         currentUserId = mUserController.getCurrentUserIdLocked();
57 
58         //讀取urigrants.xml,為其中定義的ContentProvider配置對指定Uri數據的訪問/修改權限
59         //原生代碼中,似乎沒有urigrants.xml文件
60         //實際使用的grant-uri-permission是分布式定義的
61         readGrantedUriPermissionsLocked();
62     }
63     ..........
View Code

這一部分的工作主要是調用一些關鍵服務的初始化函數,
然后殺死那些沒有FLAG_PERSISTENT卻在AMS啟動完成前已經存在的進程,
同時獲取一些配置參數。
需要注意的是,由於只有Java進程才會向AMS注冊,而一般的Native進程不會向AMS注冊,因此此處殺死的進程是Java進程。

 

階段二

 1 //1、調用參數傳入的runnable對象,SystemServer中有具體的定義
 2 if (goingCallback != null) goingCallback.run();
 3 ..............
 4 //調用所有系統服務的onStartUser接口
 5 mSystemServiceManager.startUser(currentUserId);
 6 .............
 7 synchronized (this) {
 8     // Only start up encryption-aware persistent apps; once user is
 9     // unlocked we'll come back around and start unaware apps
10     2、啟動persistent為1的application所在的進程
11     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12 
13     // Start up initial activity.
14     mBooting = true;
15 
16     // Enable home activity for system user, so that the system can always boot
17     //當isSplitSystemUser返回true時,意味者system user和primary user是分離的
18     //這里應該是讓system user也有啟動home activity的權限吧
19     if (UserManager.isSplitSystemUser()) {
20         ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
21         try {
22             AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
23                     PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
24                     UserHandle.USER_SYSTEM);
25         } catch (RemoteException e) {
26             throw e.rethrowAsRuntimeException();
27         }
28     }
29 
30     //3、啟動Home
31     startHomeActivityLocked(currentUserId, "systemReady");
32 
33     try {
34         //發送消息,觸發處理Uid錯誤的Application
35         if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
36             ..........
37             mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
38         }
39     } catch (RemoteException e) {
40     }
41     //發送一些廣播信息
42     ............
43     //這里暫時先不深入,等進一步了解Activity的啟動過程后,再做了解
44     mStackSupervisor.resumeFocusedStackTopActivityLocked();
45     ............
46 }
47 .............
View Code

從部分代碼來看,主要的工作就是通知一些服務可以進行systemReady相關的工作,並進行啟動服務或應用進程的工作。

 

2.4.1 調用回調接口
回調接口的具體內容定義與SystemServer.java中,其中會調用大量服務的onBootPhase函數、一些對象的systemReady函數或systemRunning函數。
此處,我們僅截取一些比較特別的內容:

 1 public void run() {
 2     ............
 3     try {
 4         //啟動NativeCrashListener監聽"/data/system/ndebugsocket"中的信息
 5         //實際上是監聽debuggerd傳入的信息
 6         mActivityManagerService.startObservingNativeCrashes();
 7     } catch (Throwable e) {
 8         reportWtf("observing native crashes", e);
 9     }
10     ............
11     try {
12         //啟動SystemUi
13         startSystemUi(context);
14     } catch (Throwable e) {
15         reportWtf("starting System UI", e);
16     }
17     ............
18     //這個以前分析過,啟動Watchdog
19     Watchdog.getInstance().start();
20     ....................
21 }

 回調接口中的內容較多,不做一一分析。

 

2.4.2 啟動persistent標志的進程
我們看看startPersistentApps對應的內容:

 1 private void startPersistentApps(int matchFlags) {
 2     .............
 3 
 4     synchronized (this) {
 5         try {
 6             //從PKMS中得到persistent為1的ApplicationInfo
 7             final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
 8                     .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
 9             for (ApplicationInfo app : apps) {
10                 //由於framework-res.apk已經由系統啟動,所以此處不再啟動它
11                 if (!"android".equals(app.packageName)) {
12                     //addAppLocked中將啟動application所在進程
13                     addAppLocked(app, false, null /* ABI override */);
14                 }
15             }
16         } catch (RemoteException ex) {
17         }
18     }
19 }

 

跟進一下addAppLocked函數:

 1 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
 2         String abiOverride) {
 3     //以下是取出或構造出ApplicationInfo對應的ProcessRecord
 4     ProcessRecord app;
 5     if (!isolated) {
 6         app = getProcessRecordLocked(info.processName, info.uid, true);
 7     } else {
 8         app = null;
 9     }
10 
11     if (app == null) {
12         app = newProcessRecordLocked(info, null, isolated, 0);
13         updateLruProcessLocked(app, false, null);
14         updateOomAdjLocked();
15     }
16     ...........
17     // This package really, really can not be stopped.
18     try {
19         //通過PKMS將package對應數據結構的StoppedState置為fasle
20         AppGlobals.getPackageManager().setPackageStoppedState(
21                 info.packageName, false, UserHandle.getUserId(app.uid));
22     } catch (RemoteException e) {
23     } catch (IllegalArgumentException e) {
24         Slog.w(TAG, "Failed trying to unstop package "
25                 + info.packageName + ": " + e);
26     }
27 
28     if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
29         app.persistent = true;
30         app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
31     }
32 
33     if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
34         mPersistentStartingProcesses.add(app);
35         //啟動應用所在進程,將發送消息給zygote,后者fork出進程
36         startProcessLocked(app, "added application", app.processName, abiOverride,
37                 null /* entryPoint */, null /* entryPointArgs */);
38     }
39 
40     return app;
41 }

這里最終將通過startProcessLocked函數,啟動實際的應用進程。
正如之前分析zygote進程時,提過的一樣,zygote中的server socket將接收消息,然后為應用fork出進程。

 

2.4.3 啟動Home Activity
看看啟動Home Activity對應的startHomeActivityLocked函數:

 1 boolean startHomeActivityLocked(int userId, String reason) {
 2     ..............
 3     Intent intent = getHomeIntent();
 4     //根據intent中攜帶的ComponentName,利用PKMS得到ActivityInfo
 5     ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
 6     if (aInfo != null) {
 7         intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
 8         aInfo = new ActivityInfo(aInfo);
 9         aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
10 
11         //此時home對應進程應該還沒啟動,app為null
12         ProcessRecord app = getProcessRecordLocked(aInfo.processName,
13                 aInfo.applicationInfo.uid, true);
14         if (app == null || app.instrumentationClass == null) {
15             intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
16             //啟動home
17             mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
18         }
19     } else {
20         ..........
21     }
22     return true;
23 }

這里暫時先不深究Home Activity啟動的具體過程。


從手頭的資料來看,當Home Activity啟動后,
ActivityStackSupervisor中的activityIdleInternalLocked函數將被調用(具體調用過程,還需要研究):

1 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2         Configuration config) {
3     ...........
4     if (isFocusedStack(r.task.stack) || fromTimeout) {
5         booting = checkFinishBootingLocked();
6     }
7     ............
8 }

 

在checkFinishBootingLocked函數中:

 1 private boolean checkFinishBootingLocked() {
 2     //mService為AMS,mBooting變量在AMS回調SystemServer中定義的Runnable時,置為了true
 3     final boolean booting = mService.mBooting;
 4     boolean enableScreen = false;
 5     mService.mBooting = false;
 6     if (!mService.mBooted) {
 7         mService.mBooted = true;
 8         enableScreen = true;
 9     }
10     if (booting || enableScreen) {、
11         //調用AMS的接口,發送消息
12         mService.postFinishBooting(booting, enableScreen);
13     }
14     return booting;
15 }

 

最終,AMS的finishBooting函數將被調用:

 1 final void finishBooting() {
 2     .........
 3     //以下是注冊廣播接收器,用於處理需要重啟的package
 4     IntentFilter pkgFilter = new IntentFilter();
 5     pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
 6     pkgFilter.addDataScheme("package");
 7     mContext.registerReceiver(new BroadcastReceiver() {
 8         @Override
 9         public void onReceive(Context context, Intent intent) {
10             String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
11             if (pkgs != null) {
12                 for (String pkg : pkgs) {
13                     synchronized (ActivityManagerService.this) {
14                         if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
15                                 0, "query restart")) {
16                             setResultCode(Activity.RESULT_OK);
17                             return;
18                         }
19                     }
20                 }
21             }
22        }
23     }, pkgFilter);
24     ...........
25     // Let system services know.
26     mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
27 
28     //以下是啟動那些等待啟動的進程
29     synchronized (this) {
30         // Ensure that any processes we had put on hold are now started
31         // up.
32         final int NP = mProcessesOnHold.size();
33             if (NP > 0) {
34                 ArrayList<ProcessRecord> procs =
35                         new ArrayList<ProcessRecord>(mProcessesOnHold);
36                 for (int ip=0; ip<NP; ip++) {
37                     .................
38                     startProcessLocked(procs.get(ip), "on-hold", null);
39                 }
40             }
41         }
42     }
43     ..............
44     if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
45         // Start looking for apps that are abusing wake locks.
46         //每15min檢查一次系統各應用進程使用電量的情況,如果某個進程使用WakeLock的時間過長
47         //AMS將關閉該進程
48         Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
49         mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
50 
51         // Tell anyone interested that we are done booting!
52         SystemProperties.set("sys.boot_completed", "1");
53         .................
54         //此處從代碼來看發送的是ACTION_LOCKED_BOOT_COMPLETED廣播
55         //在進行unlock相關的工作后,mUserController將調用finishUserUnlocking,發送SYSTEM_USER_UNLOCK_MSG消息給AMS
56         //AMS收到消息后,調用mUserController的finishUserUnlocked函數,經過相應的處理后,
57         //在mUserController的finishUserUnlockedCompleted中,最終將會發送ACTION_BOOT_COMPLETED廣播
58         mUserController.sendBootCompletedLocked(.........);
59         .................
60     }
61 }
View Code

 

最終,當AMS啟動Home Activity結束,並發送ACTION_BOOT_COMPLETED廣播時,AMS的啟動過程告一段落。



總結圖


 

 


免責聲明!

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



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