一. 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 }
從代碼來看,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 ..........
這一部分的工作主要是調用一些關鍵服務的初始化函數,
然后殺死那些沒有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 .............
從部分代碼來看,主要的工作就是通知一些服務可以進行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 }
最終,當AMS啟動Home Activity結束,並發送ACTION_BOOT_COMPLETED廣播時,AMS的啟動過程告一段落。
總結圖