ActivityManagerService分析一:AMS的启动

这一章我们开始分析ActivityManagerService,在后面的介绍中,我们简称为AMS。AMS并不是只用于管理所有的Activity的生命周期,它同时也管理着系统的service、broadcast以及provider等。我们首先还是从AMS的启动开始分析,它的构造以及运行都是在SystemServer当中:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. context = ActivityManagerService.main(factoryTest);  
  2.   
  3. ActivityManagerService.setSystemProcess();  
  4.   
  5. ActivityManagerService.installSystemProviders();  
  6.   
  7. ActivityManagerService.self().setWindowManager(wm);  
  8.   
  9. ActivityManagerService.self().systemReady(new Runnable()   
  10.   
  11. ActivityManagerService.self().startObservingNativeCrashes();  


在SystemServer当中主要调用AMS的上面几个方法,其中通过AMS的main方法返回的context提供给其它Service上下文使用。我们接下来一个个分析上面几个函数,首先来看main方法:

ActivityManagerService的main方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static final Context main(int factoryTest) {  
  2.     AThread thr = new AThread();  
  3.     thr.start();  
  4.     synchronized (thr) {  
  5.         while (thr.mService == null) {  
  6.             try {  
  7.                 thr.wait();  
  8.             } catch (InterruptedException e) {  
  9.             }  
  10.         }  
  11.     }  
  12.     ActivityManagerService m = thr.mService;  
  13.     mSelf = m;  
  14.     ActivityThread at = ActivityThread.systemMain();  
  15.     mSystemThread = at;  
  16.     Context context = at.getSystemContext();  
  17.     context.setTheme(android.R.style.Theme_Holo);  
  18.     m.mContext = context;  
  19.     m.mFactoryTest = factoryTest;  
  20.     m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());  
  21.     m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);  
  22.     m.mBatteryStatsService.publish(context);  
  23.     m.mUsageStatsService.publish(context);  
  24.     m.mAppOpsService.publish(context);  
  25.     synchronized (thr) {  
  26.         thr.mReady = true;  
  27.         thr.notifyAll();  
  28.     }  
  29.     m.startRunning(nullnullnullnull);  
  30.     return context;  
  31. }  

AThread继承于Thread,主要用于初始化Looper并构造AMS对象赋值给它的成员变量mService,我们首先来看AMS的构造函数:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private ActivityManagerService() {  
  2.     Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());  
  3.     mFgBroadcastQueue = new BroadcastQueue(this"foreground", BROADCAST_FG_TIMEOUT, false);  
  4.     mBgBroadcastQueue = new BroadcastQueue(this"background", BROADCAST_BG_TIMEOUT, true);  
  5.     mBroadcastQueues[0] = mFgBroadcastQueue;  
  6.     mBroadcastQueues[1] = mBgBroadcastQueue;  
  7.     mServices = new ActiveServices(this);  
  8.     mProviderMap = new ProviderMap(this);  
  9.     File dataDir = Environment.getDataDirectory();  
  10.     File systemDir = new File(dataDir, "system");  
  11.     systemDir.mkdirs();  
  12.     mBatteryStatsService = new BatteryStatsService(new File(  
  13.             systemDir, "batterystats.bin").toString());  
  14.     mBatteryStatsService.getActiveStatistics().readLocked();  
  15.     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();  
  16.     mOnBattery = DEBUG_POWER ? true  
  17.             : mBatteryStatsService.getActiveStatistics().getIsOnBattery();  
  18.     mBatteryStatsService.getActiveStatistics().setCallback(this);  
  19.     mProcessStats = new ProcessStatsService(thisnew File(systemDir, "procstats"));  
  20.     mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());  
  21.     mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));  
  22.     mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));  
  23.     mHeadless = "1".equals(SystemProperties.get("ro.config.headless""0"));  
  24.     // User 0 is the first and only user that runs at boot.  
  25.     mStartedUsers.put(0new UserStartedState(new UserHandle(0), true));  
  26.     mUserLru.add(Integer.valueOf(0));  
  27.     updateStartedUserArrayLocked();  
  28.     GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",  
  29.         ConfigurationInfo.GL_ES_VERSION_UNDEFINED);  
  30.     mConfiguration.setToDefaults();  
  31.     mConfiguration.setLocale(Locale.getDefault());  
  32.     mConfigurationSeq = mConfiguration.seq = 1;  
  33.     mCompatModePackages = new CompatModePackages(this, systemDir);  
  34.     // Add ourself to the Watchdog monitors.  
  35.     Watchdog.getInstance().addMonitor(this);  
  36. }  

PMS的构造函数主要初始化一些成员变量,并在/data/system下面建立一些文件(夹)供系统统计数据用,现将一些文件及其作用列在下面的表格中,我们以后使用在再来分析:

Service文件路径描述
BatteryStatsService/data/system/batterystats.bin管理电池使用状态
ProcessStatsService/data/system/procstats管理进程状态
UsageStatsService/data/system/usagestats管理用户使用状态
AppOpsService/data/system/appops.xml管理进程状态
AtomicFile/data/system/urigrants.xml管理系统URI权限

回到main方法中,接着调用ActivityThread的systemMain方法去构造一个ActivityThread对象,ActivityThread是所有Application运行的主线程。这里通过systemMain去获得一个SystemContext,而一般应用程序则通过ActivityThread的main方法开始执行,我们将在后面分析到:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static ActivityThread systemMain() {  
  2.     HardwareRenderer.disable(true);  
  3.     ActivityThread thread = new ActivityThread();  
  4.     thread.attach(true);  
  5.     return thread;  
  6. }  
  7.   
  8. private void attach(boolean system) {  
  9.     sCurrentActivityThread = this;  
  10.     mSystemThread = system;  
  11.     if (!system) {  
  12.   
  13.     } else {  
  14.         android.ddm.DdmHandleAppName.setAppName("system_process",  
  15.                                                 UserHandle.myUserId());  
  16.         try {  
  17.             mInstrumentation = new Instrumentation();  
  18.             ContextImpl context = new ContextImpl();  
  19.             context.init(getSystemContext().mPackageInfo, nullthis);  
  20.             Application app = Instrumentation.newApplication(Application.class, context);  
  21.             mAllApplications.add(app);  
  22.             mInitialApplication = app;  
  23.             app.onCreate();  
  24.         } catch (Exception e) {  
  25.             throw new RuntimeException(  
  26.                     "Unable to instantiate Application():" + e.toString(), e);  
  27.         }  
  28.     }  
  29.     ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {  
  30.         @Override  
  31.         public void onConfigurationChanged(Configuration newConfig) {  
  32.             synchronized (mResourcesManager) {  
  33.                 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {  
  34.                     if (mPendingConfiguration == null ||  
  35.                             mPendingConfiguration.isOtherSeqNewer(newConfig)) {  
  36.                         mPendingConfiguration = newConfig;  
  37.                           
  38.                         sendMessage(H.CONFIGURATION_CHANGED, newConfig);  
  39.                     }  
  40.                 }  
  41.             }  
  42.         }  
  43.         @Override  
  44.         public void onLowMemory() {  
  45.         }  
  46.         @Override  
  47.         public void onTrimMemory(int level) {  
  48.         }  
  49.     });  
  50. }  

在ActivityThread的systemMain方法中,首先构造一个ActivityThread对象,然后调用它的attach方法。传入到attach方法的参数为true,我们先只看attach system的ActivityThread的流程。attach方法首先构造一个ContextImpl对象,然后调用getSystemContext来获取一个SystemContext上下文,这里成为SystemContext是因为它加载了系统中包名为"android"的应用,也就是framework-res.apk,并且mSystemContext会返回给systemServer中其它的服务使用:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public ContextImpl getSystemContext() {  
  2.     synchronized (this) {  
  3.         if (mSystemContext == null) {  
  4.             ContextImpl context =  
  5.                 ContextImpl.createSystemContext(this);  
  6.             LoadedApk info = new LoadedApk(this"android", context, null,  
  7.                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);  
  8.             context.init(info, nullthis);  
  9.             context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),  
  10.                     mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));  
  11.             mSystemContext = context;  
  12.         }  
  13.     }  
  14.     return mSystemContext;  
  15. }  

首先来看一下ContextImpl的createSystemContext方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static ContextImpl createSystemContext(ActivityThread mainThread) {  
  2.     final ContextImpl context = new ContextImpl();  
  3.     context.init(Resources.getSystem(), mainThread, Process.myUserHandle());  
  4.     return context;  
  5. }  
  6.   
  7. final void init(Resources resources, ActivityThread mainThread, UserHandle user) {  
  8.     mPackageInfo = null;  
  9.     mBasePackageName = null;  
  10.     mOpPackageName = null;  
  11.     mResources = resources;  
  12.     mMainThread = mainThread;  
  13.     mContentResolver = new ApplicationContentResolver(this, mainThread, user);  
  14.     mUser = user;  
  15. }  

在ContextImpl中有很多init函数,我们要根据它的参数来看正确的init函数。这里的init函数主要初始化一些成员变量。然后在getSystemContext构造LoadedApk对象,LoadedApk用于描述一个加载进来的APK文件:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public LoadedApk(ActivityThread activityThread, String name,  
  2.         Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {  
  3.     mActivityThread = activityThread;  
  4.     mApplicationInfo = info != null ? info : new ApplicationInfo();  
  5.     mApplicationInfo.packageName = name;  
  6.     mPackageName = name;  
  7.     mAppDir = null;  
  8.     mResDir = null;  
  9.     mSharedLibraries = null;  
  10.     mDataDir = null;  
  11.     mDataDirFile = null;  
  12.     mLibDir = null;  
  13.     mBaseClassLoader = null;  
  14.     mSecurityViolation = false;  
  15.     mIncludeCode = true;  
  16.     mClassLoader = systemContext.getClassLoader();  
  17.     mResources = systemContext.getResources();  
  18.     mDisplayAdjustments.setCompatibilityInfo(compatInfo);  
  19. }  

然后再调用ContextImpl的init方法来初始化mSystemContext的一些成员:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {  
  2.     init(packageInfo, activityToken, mainThread, nullnull, Process.myUserHandle());  
  3. }  
  4.   
  5. final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,  
  6.         Resources container, String basePackageName, UserHandle user) {  
  7.     mPackageInfo = packageInfo;  
  8.     if (basePackageName != null) {  
  9.   
  10.     } else {  
  11.         mBasePackageName = packageInfo.mPackageName;  
  12.         ApplicationInfo ainfo = packageInfo.getApplicationInfo();  
  13.         if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {  
  14.   
  15.         } else {  
  16.             mOpPackageName = mBasePackageName;  
  17.         }  
  18.     }  
  19.     mResources = mPackageInfo.getResources(mainThread);  
  20.     mResourcesManager = ResourcesManager.getInstance();  
  21.   
  22.     CompatibilityInfo compatInfo =  
  23.             container == null ? null : container.getCompatibilityInfo();  
  24.     if (mResources != null &&  
  25.             ((compatInfo != null && compatInfo.applicationScale !=  
  26.                     mResources.getCompatibilityInfo().applicationScale)  
  27.             || activityToken != null)) {  
  28.   
  29.     } else {  
  30.         mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());  
  31.         mDisplayAdjustments.setActivityToken(activityToken);  
  32.     }  
  33.     mMainThread = mainThread;  
  34.     mActivityToken = activityToken;  
  35.     mContentResolver = new ApplicationContentResolver(this, mainThread, user);  
  36.     mUser = user;  
  37. }  

这里的mBasePackageName和mOpPackageName都是"android"。回到ActivityThread的attach方法中,接着调用Instrumentation的newApplication构造一个Application对象并将它设置为mInitialApplication,并添加到mAllApplications数组中,由此我们也可以看出,一个ActivityThread(也就是一个进程)中可以运行多个application,这里application都保存在mAllApplications,其中第一个运行的application保存在mInitialApplication。最后调用Application的oncreate方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static public Application newApplication(Class<?> clazz, Context context)  
  2.         throws InstantiationException, IllegalAccessException,   
  3.         ClassNotFoundException {  
  4.     Application app = (Application)clazz.newInstance();  
  5.     app.attach(context);  
  6.     return app;  
  7. }  
  8.   
  9. /* package */ final void attach(Context context) {  
  10.     attachBaseContext(context);  
  11.     mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;  
  12. }  

在ActivityThread的attach方法的最后,向ViewRootImpl注册一个callback用于接收ConfigurationChanged事件(例如横竖屏切换、输入法弹出等),我们将在介绍WindowsManager的时候来分析如果dispatch这些事件到具体的activity当中。回到AMS的main方法中,接着将getSystemContext设置为刚创建的ActivityThread,并设置AMS中mContext为ActivityThread中的mSystemContext,然后向ServiceManager注册三个service后就调用AMS的startRunning开始AMS的运行:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public final void startRunning(String pkg, String cls, String action,  
  2.         String data) {  
  3.     synchronized(this) {  
  4.         if (mStartRunning) {  
  5.             return;  
  6.         }  
  7.         mStartRunning = true;  
  8.         mTopComponent = pkg != null && cls != null  
  9.                 ? new ComponentName(pkg, cls) : null;  
  10.         mTopAction = action != null ? action : Intent.ACTION_MAIN;  
  11.         mTopData = data;  
  12.         if (!mSystemReady) {  
  13.             return;  
  14.         }  
  15.     }  
  16.     systemReady(null);  
  17. }  

因为进入startRunning时mStartRunning和mSystemReady都为false,所以这里只是设置mStartRunning为true,mTopComponent为null,mTopAction为Intent.ACTION_MAIN,mTopData为null就直接返回。到这里AMS的main方法就介绍完了,回到systemServer调用AMS的第二个函数是setSystemProcess:

ActivityManagerService的setSystemProcess方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static void setSystemProcess() {  
  2.     try {  
  3.         ActivityManagerService m = mSelf;  
  4.         ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);  
  5.         ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);  
  6.         ServiceManager.addService("meminfo"new MemBinder(m));  
  7.         ServiceManager.addService("gfxinfo"new GraphicsBinder(m));  
  8.         ServiceManager.addService("dbinfo"new DbBinder(m));  
  9.         if (MONITOR_CPU_USAGE) {  
  10.             ServiceManager.addService("cpuinfo"new CpuBinder(m));  
  11.         }  
  12.         ServiceManager.addService("permission"new PermissionController(m));  
  13.         ApplicationInfo info =  
  14.             mSelf.mContext.getPackageManager().getApplicationInfo(  
  15.                         "android", STOCK_PM_FLAGS);  
  16.         mSystemThread.installSystemApplicationInfo(info);  
  17.         synchronized (mSelf) {  
  18.             ProcessRecord app = mSelf.newProcessRecordLocked(info,  
  19.                     info.processName, false);  
  20.             app.persistent = true;  
  21.             app.pid = MY_PID;  
  22.             app.maxAdj = ProcessList.SYSTEM_ADJ;  
  23.             app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);  
  24.             mSelf.mProcessNames.put(app.processName, app.uid, app);  
  25.             synchronized (mSelf.mPidsSelfLocked) {  
  26.                 mSelf.mPidsSelfLocked.put(app.pid, app);  
  27.             }  
  28.             mSelf.updateLruProcessLocked(app, falsenull);  
  29.             mSelf.updateOomAdjLocked();  
  30.         }  
  31.     } catch (PackageManager.NameNotFoundException e) {  
  32.         throw new RuntimeException(  
  33.                 "Unable to find android system package", e);  
  34.     }  
  35. }  

这里首先向ServiceManager注册几个服务,然后PMS的getApplicationInfo去获取packageName为"android"的信息,我们知道包名为"android"的APK其实就是"framework-res.apk",PMS的getApplicationInfo比较简单,都是获取在scanPackageLI保存的mAndroidApplication对象,然后调用mSystemThread的installSystemApplicationInfo将前面获取到的"framework-res.apk"的ApplicantionInfo绑定到mSystemThread的Context上。接着setSystemProcess调用newProcessRecordLocked方法创建一个ProcessRecord对象,ProcessRecord描述一个进程的信息,这里代表framework-res.apk所在的进程信息(也就是systemServer的进程):

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,  
  2.         boolean isolated) {  
  3.     String proc = customProcess != null ? customProcess : info.processName;  
  4.     BatteryStatsImpl.Uid.Proc ps = null;  
  5.     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();  
  6.     int uid = info.uid;  
  7.     return new ProcessRecord(stats, info, proc, uid);  
  8. }  
  9.   
  10. ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,  
  11.         String _processName, int _uid) {  
  12.     mBatteryStats = _batteryStats;  
  13.     info = _info;  
  14.     isolated = _info.uid != _uid;  
  15.     uid = _uid;  
  16.     userId = UserHandle.getUserId(_uid);  
  17.     processName = _processName;  
  18.     pkgList.put(_info.packageName, null);  
  19.     maxAdj = ProcessList.UNKNOWN_ADJ;  
  20.     curRawAdj = setRawAdj = -100;  
  21.     curAdj = setAdj = -100;  
  22.     persistent = false;  
  23.     removed = false;  
  24.     lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();  
  25. }  

ProcessRecord记录了当前ApplicationInfo的uid号、processName、以及进程优先级等,并且在pkgList保存了所有在当前进程中的package信息。回到setSystemProcess中将刚创建的ProcessRecord设置为常驻内存,pid号设置为systemServer的进程号。app.makeActive方法用于调用ProcessStatsService开始记录process的状态:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {  
  2.     if (thread == null) {  
  3.         final ProcessStats.ProcessState origBase = baseProcessTracker;  
  4.         if (origBase != null) {  
  5.   
  6.         }  
  7.         baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,  
  8.                 processName);  
  9.         baseProcessTracker.makeActive();  
  10.         for (int i=0; i<pkgList.size(); i++) {  
  11.             ProcessStats.ProcessState ps = pkgList.valueAt(i);  
  12.             if (ps != null && ps != origBase) {  
  13.                 ps.makeInactive();  
  14.             }  
  15.             ps = tracker.getProcessStateLocked(pkgList.keyAt(i), info.uid, processName);  
  16.             if (ps != baseProcessTracker) {  
  17.                 ps.makeActive();  
  18.             }  
  19.             pkgList.setValueAt(i, ps);  
  20.         }  
  21.     }  
  22.     thread = _thread;  
  23. }  

makeActive中调用两次getProcessStateLocked去获取ProcessState,其实这两次中的参数完全一样,所以pkgList保持的"system"对应的ProcessState也就是baseProcessTracker。先来看ProcessStatsService的getProcessStateLocked方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public ProcessStats.ProcessState getProcessStateLocked(String packageName,  
  2.         int uid, String processName) {  
  3.     return mProcessStats.getProcessStateLocked(packageName, uid, processName);  
  4. }  
  5.   
  6. public ProcessState getProcessStateLocked(String packageName, int uid, String processName) {  
  7.     final PackageState pkgState = getPackageStateLocked(packageName, uid);  
  8.     ProcessState ps = pkgState.mProcesses.get(processName);  
  9.     if (ps != null) {  
  10.         return ps;  
  11.     }  
  12.     ProcessState commonProc = mProcesses.get(processName, uid);  
  13.     if (commonProc == null) {  
  14.         commonProc = new ProcessState(this, packageName, uid, processName);  
  15.         mProcesses.put(processName, uid, commonProc);  
  16.         if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc);  
  17.     }  
  18.     if (!commonProc.mMultiPackage) {  
  19.         if (packageName.equals(commonProc.mPackage)) {  
  20.             ps = commonProc;  
  21.             if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc);  
  22.         } else {  
  23.   
  24.         }  
  25.     } else {  
  26.   
  27.     }  
  28.     pkgState.mProcesses.put(processName, ps);  
  29.     if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps);  
  30.     return ps;  
  31. }  

这里会构造PackageState和ProcessState,并分别添加到mPackages和mProcesses数组中,并将ProcessState添加到PackageState的mProcesses数组中,从这里可以看到,一个Package可以运行在几个process里面,通过一个process也可以运行几个package。下面是上述几个类的结构图:



最后将当前ProcessRecord加入到mProcessNames和mPidsSelfLocked数据结构当中。updateLruProcessLocked用于调整系统优先级,updateOomAdjLocked用于low memory killer,我们将在后面再来介绍。

我们再来看systemServer调用AMS的第三个方法installSystemProviders,这个方法其实就是用来安装SettingsProvider:

ActivityManagerService的installSystemProviders方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static final void installSystemProviders() {  
  2.     List<ProviderInfo> providers;  
  3.     synchronized (mSelf) {  
  4.         ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);  
  5.         providers = mSelf.generateApplicationProvidersLocked(app);  
  6.         if (providers != null) {  
  7.             for (int i=providers.size()-1; i>=0; i--) {  
  8.                 ProviderInfo pi = (ProviderInfo)providers.get(i);  
  9.                 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {  
  10.                     Slog.w(TAG, "Not installing system proc provider " + pi.name  
  11.                             + ": not system .apk");  
  12.                     providers.remove(i);  
  13.                 }  
  14.             }  
  15.         }  
  16.     }  
  17.     if (providers != null) {  
  18.         mSystemThread.installSystemProviders(providers);  
  19.     }  
  20.     mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);  
  21.     mSelf.mUsageStatsService.monitorPackages();  
  22. }  

这里首先获取前面在setSystemProcess添加到mProcessNames数组当中的ProcessRecord对象,然后调用generateApplicationProvidersLocked从PMS中找到"SettingsProvider.apk"提供的provider,我们可以到SettingsProvider的manifest文件中先看一下这个provider的信息:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.         package="com.android.providers.settings"  
  3.         coreApp="true"  
  4.         android:sharedUserId="android.uid.system">  
  5.     <application android:allowClearUserData="false"  
  6.                  android:label="@string/app_label"  
  7.                  android:process="system"  
  8.                  android:backupAgent="SettingsBackupAgent"  
  9.                  android:killAfterRestore="false"  
  10.                  android:icon="@mipmap/ic_launcher_settings">  
  11.                    
  12.     <!-- todo add: android:neverEncrypt="true" -->  
  13.         <provider android:name="SettingsProvider" android:authorities="settings"  
  14.                   android:multiprocess="false"  
  15.                   android:exported="true"  
  16.                   android:writePermission="android.permission.WRITE_SETTINGS"  
  17.                   android:initOrder="100" />  
  18.     </application>  
  19. </manifest>  

可以看到这个apk的processName也是"system",并且UID也是"android.uid.system"。再来分析generateApplicationProvidersLocked方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {  
  2.     List<ProviderInfo> providers = null;  
  3.     try {  
  4.         providers = AppGlobals.getPackageManager().  
  5.             queryContentProviders(app.processName, app.uid,  
  6.                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);  
  7.     } catch (RemoteException ex) {  
  8.     }  
  9.     int userId = app.userId;  
  10.     if (providers != null) {  
  11.         int N = providers.size();  
  12.         app.pubProviders.ensureCapacity(N + app.pubProviders.size());  
  13.         for (int i=0; i<N; i++) {  
  14.             ProviderInfo cpi =  
  15.                 (ProviderInfo)providers.get(i);  
  16.   
  17.             ComponentName comp = new ComponentName(cpi.packageName, cpi.name);  
  18.             ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);  
  19.             if (cpr == null) {  
  20.                 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);  
  21.                 mProviderMap.putProviderByClass(comp, cpr);  
  22.             }  
  23.             app.pubProviders.put(cpi.name, cpr);  
  24.             if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {  
  25.                 app.addPackage(cpi.applicationInfo.packageName, mProcessStats);  
  26.             }  
  27.             ensurePackageDexOpt(cpi.applicationInfo.packageName);  
  28.         }  
  29.     }  
  30.     return providers;  
  31. }  

首先调用PMS的queryContentProviders来查询processName和uid与上面相同的provider:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public List<ProviderInfo> queryContentProviders(String processName,  
  2.         int uid, int flags) {  
  3.     ArrayList<ProviderInfo> finalList = null;  
  4.     // reader  
  5.     synchronized (mPackages) {  
  6.         final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();  
  7.         final int userId = processName != null ?  
  8.                 UserHandle.getUserId(uid) : UserHandle.getCallingUserId();  
  9.         while (i.hasNext()) {  
  10.             final PackageParser.Provider p = i.next();  
  11.             PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);  
  12.             if (ps != null && p.info.authority != null  
  13.                     && (processName == null  
  14.                             || (p.info.processName.equals(processName)  
  15.                                     && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))  
  16.                     && mSettings.isEnabledLPr(p.info, flags, userId)  
  17.                     && (!mSafeMode  
  18.                             || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {  
  19.                 if (finalList == null) {  
  20.                     finalList = new ArrayList<ProviderInfo>(3);  
  21.                 }  
  22.                 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,  
  23.                         ps.readUserState(userId), userId);  
  24.                 if (info != null) {  
  25.                     finalList.add(info);  
  26.                 }  
  27.             }  
  28.         }  
  29.     }  
  30.   
  31.     if (finalList != null) {  
  32.         Collections.sort(finalList, mProviderInitOrderSorter);  
  33.     }  
  34.   
  35.     return finalList;  
  36. }  

queryContentProviders迭代的从mProviders中查找processName为"system",uid为"SYSTEM_UID"的provider,然后调用generateProviderInfo去copy一份查找的provider信息并添加finalList中。回到前面的generateApplicationProvidersLocked,因为当前provider的processName为"system",所以singleton为true。接着把查询到的SetttingsProvider添加到AMS的mProviderMap数据结构和ProcessRecord的pubProviders数据结构当中。并把SettingsProvider这个package添加到ProcessRecord的pkgList里,这时ProcessRecord就有两个package在它里面了:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public boolean addPackage(String pkg, ProcessStatsService tracker) {  
  2.     if (!pkgList.containsKey(pkg)) {  
  3.         if (baseProcessTracker != null) {  
  4.             ProcessStats.ProcessState state = tracker.getProcessStateLocked(  
  5.                     pkg, info.uid, processName);  
  6.             pkgList.put(pkg, state);  
  7.             if (state != baseProcessTracker) {  
  8.                 state.makeActive();  
  9.             }  
  10.         } else {  
  11.             pkgList.put(pkg, null);  
  12.         }  
  13.         return true;  
  14.     }  
  15.     return false;  
  16. }  

先来看一下AMS和ProcessRecord中保存SettingsProvider的数据结构:



我们知道,这里的pkg为"com.android.providers.settings",通过getProcessStateLocked方法会新建一个ProcessState加入到pkgList中:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public ProcessState getProcessStateLocked(String packageName, int uid, String processName) {  
  2.     final PackageState pkgState = getPackageStateLocked(packageName, uid);  
  3.     ProcessState ps = pkgState.mProcesses.get(processName);  
  4.     if (ps != null) {  
  5.         return ps;  
  6.     }  
  7.     ProcessState commonProc = mProcesses.get(processName, uid);  
  8.     if (commonProc == null) {  
  9.   
  10.     }  
  11.     if (!commonProc.mMultiPackage) {  
  12.         if (packageName.equals(commonProc.mPackage)) {  
  13.   
  14.         } else {  
  15.   
  16.             commonProc.mMultiPackage = true;  
  17.             long now = SystemClock.uptimeMillis();  
  18.             final PackageState commonPkgState = getPackageStateLocked(commonProc.mPackage, uid);  
  19.             if (commonPkgState != null) {  
  20.                 ProcessState cloned = commonProc.clone(commonProc.mPackage, now);  
  21.                 commonPkgState.mProcesses.put(commonProc.mName, cloned);  
  22.   
  23.             ps = new ProcessState(commonProc, packageName, uid, processName, now);  
  24.             if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);  
  25.         }  
  26.     } else {  
  27.   
  28.     }  
  29.     pkgState.mProcesses.put(processName, ps);  
  30.     if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps);  
  31.     return ps;  
  32. }  
从前面ProcessRecord的makeActive可知,PackageStates中的mPackages数组保存了一个packageName为“android”的PackageState对象PA1,mProcesses保存了一个processName为“system"的ProcessState对象PS1。所以getPackageStateLocked首先还是会创建一个packageName为"com.android.providers.settings"的PackageState对象PA2添加到mPackages数组;然后从mProcesses获取前面processName为“system"的ProcessState对象PS1,此时PS1的pacakgeName与参数中的packageName并不相同,所以这里首先更改commonProc的mMultiPackage为true,然后clone一个ProcessState并替换掉前面保存在PA1的mProcesses数组中PS1。最后再通过PS1创建一个ProcessState并添加刚新创建PA2的mProcesses数组中。注意这里新创建的ProcessState都没有加入到全局的mProcesses数组中,全局mProcesses中还是仅保存PS1。上面的ProcessState的数据结构如下图:



回到AMS的installSystemProviders方法中,接着调用mSystemThread.installSystemProviders,ActivityThread是所有APK运行的主线程,所以这里会构造SettingsProvider对象,并执行它的一些回调函数,让SettingsProvider做好初始化动作:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public final void installSystemProviders(List<ProviderInfo> providers) {  
  2.     if (providers != null) {  
  3.         installContentProviders(mInitialApplication, providers);  
  4.     }  
  5. }  
  6.   
  7. private void installContentProviders(  
  8.         Context context, List<ProviderInfo> providers) {  
  9.     final ArrayList<IActivityManager.ContentProviderHolder> results =  
  10.         new ArrayList<IActivityManager.ContentProviderHolder>();  
  11.     for (ProviderInfo cpi : providers) {  
  12.         IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,  
  13.                 false /*noisy*/true /*noReleaseNeeded*/true /*stable*/);  
  14.         if (cph != null) {  
  15.             cph.noReleaseNeeded = true;  
  16.             results.add(cph);  
  17.         }  
  18.     }  
  19.     try {  
  20.         ActivityManagerNative.getDefault().publishContentProviders(  
  21.             getApplicationThread(), results);  
  22.     } catch (RemoteException ex) {  
  23.     }  
  24. }  

installContentProviders分为两步,第一步调用installProvider获得一个ContentProviderHolder对象;第二步通过AMS的publishContentProviders方法来完成注册。首先来看installProvider方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private IActivityManager.ContentProviderHolder installProvider(Context context,  
  2.         IActivityManager.ContentProviderHolder holder, ProviderInfo info,  
  3.         boolean noisy, boolean noReleaseNeeded, boolean stable) {  
  4.     ContentProvider localProvider = null;  
  5.     IContentProvider provider;  
  6.     if (holder == null || holder.provider == null) {  
  7.         Context c = null;  
  8.         ApplicationInfo ai = info.applicationInfo;  
  9.         if (context.getPackageName().equals(ai.packageName)) {  
  10.   
  11.         } else if (mInitialApplication != null &&  
  12.                 mInitialApplication.getPackageName().equals(ai.packageName)) {  
  13.   
  14.         } else {  
  15.             try {  
  16.                 c = context.createPackageContext(ai.packageName,  
  17.                         Context.CONTEXT_INCLUDE_CODE);  
  18.             } catch (PackageManager.NameNotFoundException e) {  
  19.                 // Ignore  
  20.             }  
  21.         }  
  22.   
  23.         try {  
  24.             final java.lang.ClassLoader cl = c.getClassLoader();  
  25.             localProvider = (ContentProvider)cl.  
  26.                 loadClass(info.name).newInstance();  
  27.             provider = localProvider.getIContentProvider();  
  28.   
  29.             localProvider.attachInfo(c, info);  
  30.         } catch (java.lang.Exception e) {  
  31.             if (!mInstrumentation.onException(null, e)) {  
  32.                 throw new RuntimeException(  
  33.                         "Unable to get provider " + info.name  
  34.                         + ": " + e.toString(), e);  
  35.             }  
  36.             return null;  
  37.         }  
  38.     } else {  
  39.   
  40.     }  
  41.     IActivityManager.ContentProviderHolder retHolder;  
  42.     synchronized (mProviderMap) {  
  43.         IBinder jBinder = provider.asBinder();  
  44.         if (localProvider != null) {  
  45.             ComponentName cname = new ComponentName(info.packageName, info.name);  
  46.             ProviderClientRecord pr = mLocalProvidersByName.get(cname);  
  47.             if (pr != null) {  
  48.   
  49.             } else {  
  50.                 holder = new IActivityManager.ContentProviderHolder(info);  
  51.                 holder.provider = provider;  
  52.                 holder.noReleaseNeeded = true;  
  53.                 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);  
  54.                 mLocalProviders.put(jBinder, pr);  
  55.                 mLocalProvidersByName.put(cname, pr);  
  56.             }  
  57.             retHolder = pr.mHolder;  
  58.         } else {  
  59.   
  60.         }  
  61.     }  
  62.     return retHolder;  
  63. }  

installProvider方法首先调用ContextImpl的createPackageContext方法去构造SettingsProvider所在的Context环境,在createPackageContext主要是构造一个LoadedApk对象来描述SettingsProvider这个APK,然后通过LoadedApk来初始化一个ContextImpl对象并返回,有兴趣的可以去看一下这部分code。接下来实例化一个SettingsProvider对象,SettingsProvider是继承于ContentProvider的。首先来看一下SettingsProvider的类图结构:




所以localProvider.getIContentProvider获取到一个Transport对象,Transport继承于Binder。接着调用SettingsProvider的attachInfo方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void attachInfo(Context context, ProviderInfo info) {  
  2.     attachInfo(context, info, false);  
  3. }  
  4. private void attachInfo(Context context, ProviderInfo info, boolean testing) {  
  5.     AsyncTask.init();  
  6.     mNoPerms = testing;  
  7.     if (mContext == null) {  
  8.         mContext = context;  
  9.         if (context != null) {  
  10.             mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(  
  11.                     Context.APP_OPS_SERVICE);  
  12.         }  
  13.         mMyUid = Process.myUid();  
  14.         if (info != null) {  
  15.             setReadPermission(info.readPermission);  
  16.             setWritePermission(info.writePermission);  
  17.             setPathPermissions(info.pathPermissions);  
  18.             mExported = info.exported;  
  19.         }  
  20.         ContentProvider.this.onCreate();  
  21.     }  
  22. }  

attachInfo主要根据ProviderInfo设置ContentProvider的一些属性以及读写权限,然后回调SettingsProvider的onCreate方法。最后installProvider方法调用installProviderAuthoritiesLocked方法构造一个ProviderClientRecord对象,并添加到mProviderMap、mLocalProviders和mLocalProvidersByName中,这三个ArraryMap可以通过不同键值快速找到对象的ProviderClientRecord对象。最后返回ContentProviderHolder。AcitivytThread中保存SettingsProvider的信息如下:



我们来看第二步通过AMS的publishContentProviders方法来完成注册:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public final void publishContentProviders(IApplicationThread caller,  
  2.          List<ContentProviderHolder> providers) {  
  3.      enforceNotIsolatedCaller("publishContentProviders");  
  4.      synchronized (this) {  
  5.          final ProcessRecord r = getRecordForAppLocked(caller);  
  6.   
  7.          final long origId = Binder.clearCallingIdentity();  
  8.          final int N = providers.size();  
  9.          for (int i=0; i<N; i++) {  
  10.              ContentProviderHolder src = providers.get(i);  
  11.              if (src == null || src.info == null || src.provider == null) {  
  12.                  continue;  
  13.              }  
  14.              ContentProviderRecord dst = r.pubProviders.get(src.info.name);  
  15.   
  16.              if (dst != null) {  
  17.                  ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);  
  18.                  mProviderMap.putProviderByClass(comp, dst);  
  19.                  String names[] = dst.info.authority.split(";");  
  20.                  for (int j = 0; j < names.length; j++) {  
  21.                      mProviderMap.putProviderByName(names[j], dst);  
  22.                  }  
  23.                  int NL = mLaunchingProviders.size();  
  24.                  int j;  
  25.                  for (j=0; j<NL; j++) {  
  26.                      if (mLaunchingProviders.get(j) == dst) {  
  27.                          mLaunchingProviders.remove(j);  
  28.                          j--;  
  29.                          NL--;  
  30.                      }  
  31.                  }  
  32.                  synchronized (dst) {  
  33.                      dst.provider = src.provider;  
  34.                      dst.proc = r;  
  35.                      dst.notifyAll();  
  36.                  }  
  37.                  updateOomAdjLocked(r);  
  38.              }  
  39.          }  
  40.          Binder.restoreCallingIdentity(origId);  
  41.      }  
  42.  }  

getRecordForAppLocked从mLruProcesses链表中查找并返回我们前面创建的ProcessRecord对象,我们知道在generateApplicationProvidersLocked方法中,我们将从PMS得到的SettingsProvider信息已经添加到ProcessRecord的pubProviders数组中了,这里将provider信息添加到mProviderMap中,并从mLaunchingProviders(表示待启动的provider列表)中移除已经启动的provider。最后回到installSystemProviders方法中,注册一个ContentObserver来监听Settings.Secure.LONG_PRESS_TIMEOUT的变化并调用UsageStatsService去监听package的使用状态。到这里SystemServer调用AMS的installSystemProviders就介绍完了,第四个方法setWindowManager我们先不介绍,等到介绍WMS的时候再来看。最后来看SystemServer调用systemReady方法:

ActivityManagerService的systemReady方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void systemReady(final Runnable goingCallback) {  
  2.     synchronized(this) {  
  3.         // Check to see if there are any update receivers to run.  
  4.         if (!mDidUpdate) {  
  5.             if (mWaitingUpdate) {  
  6.                 return;  
  7.             }  
  8.             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);  
  9.             List<ResolveInfo> ris = null;  
  10.             try {  
  11.                 ris = AppGlobals.getPackageManager().queryIntentReceivers(  
  12.                         intent, null00);  
  13.             } catch (RemoteException e) {  
  14.             }  
  15.             if (ris != null) {  
  16.                 for (int i=ris.size()-1; i>=0; i--) {  
  17.                     if ((ris.get(i).activityInfo.applicationInfo.flags  
  18.                             &ApplicationInfo.FLAG_SYSTEM) == 0) {  
  19.                         ris.remove(i);  
  20.                     }  
  21.                 }  
  22.                 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);  
  23.                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();  
  24.                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();  
  25.                 for (int i=0; i<ris.size(); i++) {  
  26.                     ActivityInfo ai = ris.get(i).activityInfo;  
  27.                     ComponentName comp = new ComponentName(ai.packageName, ai.name);  
  28.                     if (lastDoneReceivers.contains(comp)) {  
  29.                         ris.remove(i);  
  30.                         i--;  
  31.                     }  
  32.                 }  
  33.                 final int[] users = getUsersLocked();  
  34.                 for (int i=0; i<ris.size(); i++) {  
  35.                     ActivityInfo ai = ris.get(i).activityInfo;  
  36.                     ComponentName comp = new ComponentName(ai.packageName, ai.name);  
  37.                     doneReceivers.add(comp);  
  38.                     intent.setComponent(comp);  
  39.                     for (int j=0; j<users.length; j++) {  
  40.                         IIntentReceiver finisher = null;  
  41.                         if (i == ris.size()-1 && j == users.length-1) {  
  42.                             finisher = new IIntentReceiver.Stub() {  
  43.                                 public void performReceive(Intent intent, int resultCode,  
  44.                                         String data, Bundle extras, boolean ordered,  
  45.                                         boolean sticky, int sendingUser) {  
  46.                                     mHandler.post(new Runnable() {  
  47.                                         public void run() {  
  48.                                             synchronized (ActivityManagerService.this) {  
  49.                                                 mDidUpdate = true;  
  50.                                             }  
  51.                                             writeLastDonePreBootReceivers(doneReceivers);  
  52.                                             showBootMessage(mContext.getText(  
  53.                                                     R.string.android_upgrading_complete),  
  54.                                                     false);  
  55.                                             systemReady(goingCallback);  
  56.                                         }  
  57.                                     });  
  58.                                 }  
  59.                             };  
  60.                         }  
  61.                         Slog.i(TAG, "Sending system update to " + intent.getComponent()  
  62.                                 + " for user " + users[j]);  
  63.                         broadcastIntentLocked(nullnull, intent, null, finisher,  
  64.                                 0nullnullnull, AppOpsManager.OP_NONE,  
  65.                                 truefalse, MY_PID, Process.SYSTEM_UID,  
  66.                                 users[j]);  
  67.                         if (finisher != null) {  
  68.                             mWaitingUpdate = true;  
  69.                         }  
  70.                     }  
  71.                 }  
  72.             }  
  73.             if (mWaitingUpdate) {  
  74.                 return;  
  75.             }  
  76.             mDidUpdate = true;  
  77.         }  

这是systemReady最开始的一段code,主要用来处理OTA升级后database有改变的状况,这里会从PMS中获取所有接收ACTION_PRE_BOOT_COMPLETED的Receivers,并发送广播给它们,最后会记录这些已经发送广播的Receivers到/data/system/called_pre_boots.dat文件中。关于OTA升级这部分我们先不关注了,接着来看systemReady后面的代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ArrayList<ProcessRecord> procsToKill = null;  
  2. synchronized(mPidsSelfLocked) {  
  3.     for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {  
  4.         ProcessRecord proc = mPidsSelfLocked.valueAt(i);  
  5.         if (!isAllowedWhileBooting(proc.info)){  
  6.             if (procsToKill == null) {  
  7.                 procsToKill = new ArrayList<ProcessRecord>();  
  8.             }  
  9.             procsToKill.add(proc);  
  10.         }  
  11.     }  
  12. }  
  13.   
  14. synchronized(this) {  
  15.     if (procsToKill != null) {  
  16.         for (int i=procsToKill.size()-1; i>=0; i--) {  
  17.             ProcessRecord proc = procsToKill.get(i);  
  18.             Slog.i(TAG, "Removing system update proc: " + proc);  
  19.             removeProcessLocked(proc, truefalse"system update done");  
  20.         }  
  21.     }  
  22.       
  23.     mProcessesReady = true;  
  24. }  

上面的代码主要是杀死在AMS systemReady之前启动的启动process,且这些process没有设置FLAG_PERSISTENT(例如update进程),然后调用removeProcessLocked去结束进程并释放资源,这部分代码我们后面再来介绍。接着来看systemReady函数:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Slog.i(TAG, "System now ready");  
  2. synchronized(this) {  
  3.     if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {  
  4.   
  5.     }  
  6. }  
  7. retrieveSettings();  
  8. synchronized (this) {  
  9.     readGrantedUriPermissionsLocked();  
  10. }  
  11. if (goingCallback != null) goingCallback.run();  
  12.   
  13. synchronized (this) {  
  14.     if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {  
  15.         try {  
  16.             List apps = AppGlobals.getPackageManager().  
  17.                 getPersistentApplications(STOCK_PM_FLAGS);  
  18.             if (apps != null) {  
  19.                 int N = apps.size();  
  20.                 int i;  
  21.                 for (i=0; i<N; i++) {  
  22.                     ApplicationInfo info  
  23.                         = (ApplicationInfo)apps.get(i);  
  24.                     if (info != null &&  
  25.                             !info.packageName.equals("android")) {  
  26.                         addAppLocked(info, false);  
  27.                     }  
  28.                 }  
  29.             }  
  30.         } catch (RemoteException ex) {  
  31.             // pm is in same process, this will never happen.  
  32.         }  
  33.     }  

retrieveSettings从SettingsProvider中获取DEBUG_APP、WAIT_FOR_DEBUGGER、ALWAYS_FINISH_ACTIVITIES和DEVELOPMENT_FORCE_RTL四个配置项。readGrantedUriPermissionsLocked从/data/system/urigrants.xml中读取Uri权限,并构造UriPermission保存在AMS全局的mGrantedUriPermissions中,这部分我们以后遇到的时候再来介绍。goingCallback主要调用AMS的startObservingNativeCrashes去建立socket监听底层的NativeCrash消息,并把crash消息传递给AMS的handleApplicationCrashInner函数处理。接着从PMS中获取系统persistent的Application,并调用addAppLocked方法去启动这些Application,关于addAppLocked方法我们后面介绍启动Activity的时候再来介绍。来看systemReady最后一部分的代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.         // Start up initial activity.  
  2.         mBooting = true;  
  3.           
  4.         long ident = Binder.clearCallingIdentity();  
  5.         try {  
  6.             Intent intent = new Intent(Intent.ACTION_USER_STARTED);  
  7.             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY  
  8.                     | Intent.FLAG_RECEIVER_FOREGROUND);  
  9.             intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);  
  10.             broadcastIntentLocked(nullnull, intent,  
  11.                     nullnull0nullnullnull, AppOpsManager.OP_NONE,  
  12.                     falsefalse, MY_PID, Process.SYSTEM_UID, mCurrentUserId);  
  13.             intent = new Intent(Intent.ACTION_USER_STARTING);  
  14.             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
  15.             intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);  
  16.             broadcastIntentLocked(nullnull, intent,  
  17.                     nullnew IIntentReceiver.Stub() {  
  18.                         @Override  
  19.                         public void performReceive(Intent intent, int resultCode, String data,  
  20.                                 Bundle extras, boolean ordered, boolean sticky, int sendingUser)  
  21.                                 throws RemoteException {  
  22.                         }  
  23.                     }, 0nullnull,  
  24.                     android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,  
  25.                     truefalse, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);  
  26.         } finally {  
  27.             Binder.restoreCallingIdentity(ident);  
  28.         }  
  29.         mStackSupervisor.resumeTopActivitiesLocked();  
  30.         sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);  
  31.     }  
  32. }  

首先广播ACTION_USER_STARTED和ACTION_USER_STARTING两个消息表示user状态的改变。最后调用mStackSupervisor.resumeTopActivitiesLocked来启动HOME界面:

ActivityMangerService启动HOME

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. boolean resumeTopActivitiesLocked() {  
  2.     return resumeTopActivitiesLocked(nullnullnull);  
  3. }  
  4. boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,  
  5.         Bundle targetOptions) {  
  6.     if (targetStack == null) {  
  7.         targetStack = getFocusedStack();  
  8.     }  
  9.     boolean result = false;  
  10.     for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {  
  11.         final ActivityStack stack = mStacks.get(stackNdx);  
  12.         if (isFrontStack(stack)) {  
  13.             if (stack == targetStack) {  
  14.                 result = stack.resumeTopActivityLocked(target, targetOptions);  
  15.             } else {  
  16.                 stack.resumeTopActivityLocked(null);  
  17.             }  
  18.         }  
  19.     }  
  20.     return result;  
  21. }  
  22.   
  23. ActivityStack getFocusedStack() {  
  24.     if (mFocusedStack == null) {  
  25.         return mHomeStack;  
  26.     }  
  27.     switch (mStackState) {  
  28.         case STACK_STATE_HOME_IN_FRONT:  
  29.         case STACK_STATE_HOME_TO_FRONT:  
  30.             return mHomeStack;  
  31.         case STACK_STATE_HOME_IN_BACK:  
  32.         case STACK_STATE_HOME_TO_BACK:  
  33.         default:  
  34.             return mFocusedStack;  
  35.     }  
  36. }  

这里主要调用mHomeStack的resumeTopActivityLocked方法来启动HOME界面,mHomeStack是在setWindowManager中构造的,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void setWindowManager(WindowManagerService wm) {  
  2.     mWindowManager = wm;  
  3.     mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);  
  4.     mStacks.add(mHomeStack);  
  5. }  

来看ActivityStack的resumeTopActivityLocked函数:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {  
  2.     ActivityRecord next = topRunningActivityLocked(null);  
  3.     final boolean userLeaving = mStackSupervisor.mUserLeaving;  
  4.     mStackSupervisor.mUserLeaving = false;  
  5.     if (next == null) {  
  6.         // There are no more activities!  Let's just start up the  
  7.         // Launcher...  
  8.         ActivityOptions.abort(options);  
  9.         if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");  
  10.         if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();  
  11.         return mStackSupervisor.resumeHomeActivity(prev);  
  12.     }  

因为当前ActivityStack(HomeStack)中的mTaskHistory为空,所以这里会调用StackSupervisor的resumeHomeActivity方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. boolean resumeHomeActivity(ActivityRecord prev) {  
  2.         moveHomeToTop();  
  3.         if (prev != null) {  
  4.             prev.task.mOnTopOfHome = false;  
  5.         }  
  6.         ActivityRecord r = mHomeStack.topRunningActivityLocked(null);  
  7.         if (r != null && r.isHomeActivity()) {  
  8.   
  9.         }  
  10.         return mService.startHomeActivityLocked(mCurrentUser);  
  11.     }  
  12.   
  13.     boolean startHomeActivityLocked(int userId) {  
  14.         Intent intent = getHomeIntent();  
  15.         ActivityInfo aInfo =  
  16.             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);  
  17.         if (aInfo != null) {  
  18.             intent.setComponent(new ComponentName(  
  19.                     aInfo.applicationInfo.packageName, aInfo.name));  
  20.   
  21.             aInfo = new ActivityInfo(aInfo);  
  22.             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);  
  23.             ProcessRecord app = getProcessRecordLocked(aInfo.processName,  
  24.                     aInfo.applicationInfo.uid, true);  
  25.             if (app == null || app.instrumentationClass == null) {  
  26.                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);  
  27.                 mStackSupervisor.startHomeActivity(intent, aInfo);  
  28.             }  
  29.         }  
  30.         return true;  
  31.     }  
最终调用到AMS的startHomeActivityLocked,这里首先调用getHomeIntent构造一个Action为ACTION_MAIN,Category为CATEGORY_HOME的Intent,然后通过查找PMS中接收的所有ActivityInfo:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {  
  2.     ActivityInfo ai = null;  
  3.     ComponentName comp = intent.getComponent();  
  4.     try {  
  5.         if (comp != null) {  
  6.   
  7.         } else {  
  8.             ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(  
  9.                     intent,  
  10.                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),  
  11.                         flags, userId);  
  12.             if (info != null) {  
  13.                 ai = info.activityInfo;  
  14.             }  
  15.         }  
  16.     } catch (RemoteException e) {  
  17.         // ignore  
  18.     }  
  19.     return ai;  
  20. }  
  21.   
  22. public ResolveInfo resolveIntent(Intent intent, String resolvedType,  
  23.         int flags, int userId) {  
  24.     if (!sUserManager.exists(userId)) return null;  
  25.     enforceCrossUserPermission(Binder.getCallingUid(), userId, false"resolve intent");  
  26.     List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);  
  27.     return chooseBestActivity(intent, resolvedType, flags, query, userId);  
  28. }  

关于queryIntentActivities和chooseBestActivity我们以后再来分析,这里假设系统只有一个launcher,它的manifest文件如下:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <application  
  2.     android:name="com.android.launcher2.LauncherApplication"  
  3.     android:label="@string/application_name"  
  4.     android:icon="@mipmap/ic_launcher_home"  
  5.     android:hardwareAccelerated="true"  
  6.     android:largeHeap="@bool/config_largeHeap"  
  7.     android:supportsRtl="true">  
  8.     <activity  
  9.         android:name="com.android.launcher2.Launcher"  
  10.         android:launchMode="singleTask"  
  11.         android:clearTaskOnLaunch="true"  
  12.         android:stateNotNeeded="true"  
  13.         android:theme="@style/Theme"  
  14.         android:windowSoftInputMode="adjustPan"  
  15.         android:screenOrientation="nosensor">  
  16.         <intent-filter>  
  17.             <action android:name="android.intent.action.MAIN" />  
  18.             <category android:name="android.intent.category.HOME" />  
  19.             <category android:name="android.intent.category.DEFAULT" />  
  20.             <category android:name="android.intent.category.MONKEY"/>  
  21.         </intent-filter>  
  22.     </activity>  

在startHomeActivityLocked因为没有存在Launcher的ProcessRecord信息,所以调用mStackSupervisor.startHomeActivity去启动launcher,并且设置了FLAG_ACTIVITY_NEW_TASK,表示新建一个task来运行launcher:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void startHomeActivity(Intent intent, ActivityInfo aInfo) {  
  2.     moveHomeToTop();  
  3.     startActivityLocked(null, intent, null, aInfo, nullnull000null0,  
  4.             nullfalsenull);  
  5. }  
  6.   
  7. final int startActivityLocked(IApplicationThread caller,  
  8.         Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,  
  9.         String resultWho, int requestCode,  
  10.         int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,  
  11.         boolean componentSpecified, ActivityRecord[] outActivity) {  
  12.     int err = ActivityManager.START_SUCCESS;  
  13.     ProcessRecord callerApp = null;  
  14.     if (caller != null) {  
  15.   
  16.     }  
  17.     if (err == ActivityManager.START_SUCCESS) {  
  18.         final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;  
  19.         Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(truetruetruefalse)  
  20.                 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));  
  21.     }  
  22.     ActivityRecord sourceRecord = null;  
  23.     ActivityRecord resultRecord = null;  
  24.     if (resultTo != null) {  
  25.   
  26.     }  
  27.     ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;  
  28.     int launchFlags = intent.getFlags();  
  29.     if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0  
  30.             && sourceRecord != null) {  
  31.   
  32.     }  
  33.     if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {  
  34.   
  35.     }  
  36.     if (err == ActivityManager.START_SUCCESS && aInfo == null) {  
  37.   
  38.     }  
  39.     if (err != ActivityManager.START_SUCCESS) {  
  40.   
  41.     }  
  42.     final int startAnyPerm = mService.checkPermission(  
  43.             START_ANY_ACTIVITY, callingPid, callingUid);  
  44.     final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,  
  45.             callingUid, aInfo.applicationInfo.uid, aInfo.exported);  
  46.     if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {  
  47.   
  48.     }  
  49.     boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,  
  50.             callingPid, resolvedType, aInfo.applicationInfo);  
  51.     if (mService.mController != null) {  
  52.   
  53.     }  
  54.     if (abort) {  
  55.   
  56.     }  
  57.     ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,  
  58.             intent, resolvedType, aInfo, mService.mConfiguration,  
  59.             resultRecord, _resultWho, requestCode, componentSpecified, this);  
  60.     if (outActivity != null) {  
  61.         outActivity[0] = r;  
  62.     }  
  63.     final ActivityStack stack = getFocusedStack();  
  64.     if (stack.mResumedActivity == null  
  65.             || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {  
  66.         if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {  
  67.   
  68.         }  
  69.     }  
  70.     if (mService.mDidAppSwitch) {  
  71.         mService.mAppSwitchesAllowedTime = 0;  
  72.     } else {  
  73.         mService.mDidAppSwitch = true;  
  74.     }  
  75.     mService.doPendingActivityLaunchesLocked(false);  
  76.     err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);  
  77.     if (allPausedActivitiesComplete()) {  
  78.         dismissKeyguard();  
  79.     }  
  80.     return err;  
  81. }  

在startActivityLocked中首先做一些权限的检查,然后构造一个ActivityRecord对象,一个ActivityRecord就表示一个Activity实体,先来看一下构造ActivityRecord的参数:_service就是AMS本身,_caller为NULL,_launchedFromUid为0,_launchedFromPackage为NULL,_intent为启动Activity的Intent,_resolvedType为NULL,aInfo为从PMS获取到的ActivityInfo,_configuration为AMS的mConfiguration,_resultTo为NULL,_resultWho为NULl,_reqCode为0,_componentSpecified为false,supervisor为ActivityStackSupervisor本身:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,  
  2.         int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,  
  3.         ActivityInfo aInfo, Configuration _configuration,  
  4.         ActivityRecord _resultTo, String _resultWho, int _reqCode,  
  5.         boolean _componentSpecified, ActivityStackSupervisor supervisor) {  
  6.     service = _service;  
  7.     appToken = new Token(this);  
  8.     info = aInfo;  
  9.     launchedFromUid = _launchedFromUid;  
  10.     launchedFromPackage = _launchedFromPackage;  
  11.     userId = UserHandle.getUserId(aInfo.applicationInfo.uid);  
  12.     intent = _intent;  
  13.     shortComponentName = _intent.getComponent().flattenToShortString();  
  14.     resolvedType = _resolvedType;  
  15.     componentSpecified = _componentSpecified;  
  16.     configuration = _configuration;  
  17.     resultTo = _resultTo;  
  18.     resultWho = _resultWho;  
  19.     requestCode = _reqCode;  
  20.     state = ActivityState.INITIALIZING;  
  21.     frontOfTask = false;  
  22.     launchFailed = false;  
  23.     stopped = false;  
  24.     delayedResume = false;  
  25.     finishing = false;  
  26.     configDestroy = false;  
  27.     keysPaused = false;  
  28.     inHistory = false;  
  29.     visible = true;  
  30.     waitingVisible = false;  
  31.     nowVisible = false;  
  32.     thumbnailNeeded = false;  
  33.     idle = false;  
  34.     hasBeenLaunched = false;  
  35.     mStackSupervisor = supervisor;  
  36.     // This starts out true, since the initial state of an activity  
  37.     // is that we have everything, and we shouldn't never consider it  
  38.     // lacking in state to be removed if it dies.  
  39.     haveState = true;  
  40.     if (aInfo != null) {  
  41.         if (aInfo.targetActivity == null  
  42.                 || aInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE  
  43.                 || aInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {  
  44.             realActivity = _intent.getComponent();  
  45.         } else {  
  46.             realActivity = new ComponentName(aInfo.packageName,  
  47.                     aInfo.targetActivity);  
  48.         }  
  49.         taskAffinity = aInfo.taskAffinity;  
  50.         stateNotNeeded = (aInfo.flags&  
  51.                 ActivityInfo.FLAG_STATE_NOT_NEEDED) != 0;  
  52.         baseDir = aInfo.applicationInfo.sourceDir;  
  53.         resDir = aInfo.applicationInfo.publicSourceDir;  
  54.         dataDir = aInfo.applicationInfo.dataDir;  
  55.         nonLocalizedLabel = aInfo.nonLocalizedLabel;  
  56.         labelRes = aInfo.labelRes;  
  57.         if (nonLocalizedLabel == null && labelRes == 0) {  
  58.             ApplicationInfo app = aInfo.applicationInfo;  
  59.             nonLocalizedLabel = app.nonLocalizedLabel;  
  60.             labelRes = app.labelRes;  
  61.         }  
  62.         icon = aInfo.getIconResource();  
  63.         logo = aInfo.getLogoResource();  
  64.         theme = aInfo.getThemeResource();  
  65.         realTheme = theme;  
  66.         if (realTheme == 0) {  
  67.             realTheme = aInfo.applicationInfo.targetSdkVersion  
  68.                     < Build.VERSION_CODES.HONEYCOMB  
  69.                     ? android.R.style.Theme  
  70.                     : android.R.style.Theme_Holo;  
  71.         }  
  72.         if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {  
  73.             windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;  
  74.         }  
  75.         if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0  
  76.                 && _caller != null  
  77.                 && (aInfo.applicationInfo.uid == Process.SYSTEM_UID  
  78.                         || aInfo.applicationInfo.uid == _caller.info.uid)) {  
  79.             processName = _caller.processName;  
  80.         } else {  
  81.             processName = aInfo.processName;  
  82.         }  
  83.         if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {  
  84.             intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);  
  85.         }  
  86.         packageName = aInfo.applicationInfo.packageName;  
  87.         launchMode = aInfo.launchMode;  
  88.         AttributeCache.Entry ent = AttributeCache.instance().get(packageName,  
  89.                 realTheme, com.android.internal.R.styleable.Window, userId);  
  90.         fullscreen = ent != null && !ent.array.getBoolean(  
  91.                 com.android.internal.R.styleable.Window_windowIsFloating, false)  
  92.                 && !ent.array.getBoolean(  
  93.                 com.android.internal.R.styleable.Window_windowIsTranslucent, false);  
  94.         noDisplay = ent != null && ent.array.getBoolean(  
  95.                 com.android.internal.R.styleable.Window_windowNoDisplay, false);  
  96.         if ((!_componentSpecified || _launchedFromUid == Process.myUid()  
  97.                 || _launchedFromUid == 0) &&  
  98.                 Intent.ACTION_MAIN.equals(_intent.getAction()) &&  
  99.                 _intent.hasCategory(Intent.CATEGORY_HOME) &&  
  100.                 _intent.getCategories().size() == 1 &&  
  101.                 _intent.getData() == null &&  
  102.                 _intent.getType() == null &&  
  103.                 (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&  
  104.                 isNotResolverActivity()) {  
  105.             // This sure looks like a home activity!  
  106.             mActivityType = HOME_ACTIVITY_TYPE;  
  107.         } else if (realActivity.getClassName().contains(RECENTS_PACKAGE_NAME)) {  
  108.             mActivityType = RECENTS_ACTIVITY_TYPE;  
  109.         } else {  
  110.             mActivityType = APPLICATION_ACTIVITY_TYPE;  
  111.         }  
  112.         immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;  
  113.     }  

在ActivityRecord主要是通过ActivityInfo去设置自身的一些成员变量。然后startActivityLocked调用AMS的doPendingActivityLaunchesLocked去处理mPendingActivityLaunches中被pending中的启动Activity请求,最后调用startActivityUncheckedLocked去启动launcher这个Activity:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final int startActivityUncheckedLocked(ActivityRecord r,  
  2.         ActivityRecord sourceRecord, int startFlags, boolean doResume,  
  3.         Bundle options) {  
  4.     final Intent intent = r.intent;  
  5.     final int callingUid = r.launchedFromUid;  
  6.     int launchFlags = intent.getFlags();  
  7.   
  8.     if (!doResume) {  
  9.   
  10.     }  
  11.     ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;  
  12.   
  13.     if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {  
  14.   
  15.     }  
  16.     if (sourceRecord == null) {  
  17.         if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {  
  18.             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;  
  19.         }  
  20.     } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {  
  21.   
  22.     } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE  
  23.             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {  
  24.   
  25.     }  
  26.     ActivityInfo newTaskInfo = null;  
  27.     Intent newTaskIntent = null;  
  28.     final ActivityStack sourceStack;  
  29.     if (sourceRecord != null) {  
  30.   
  31.     } else {  
  32.         sourceStack = null;  
  33.     }  
  34.     if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {  
  35.   
  36.     }  
  37.     boolean addingToTask = false;  
  38.     boolean movedHome = false;  
  39.     TaskRecord reuseTask = null;  
  40.     ActivityStack targetStack;  
  41.     if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&  
  42.             (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)  
  43.             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK  
  44.             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {  
  45.         if (r.resultTo == null) {  
  46.             //找到与此Activity相同亲属关系的ActivityRecord  
  47.             ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE  
  48.                     ? findTaskLocked(r)  
  49.                     : findActivityLocked(intent, r.info);  
  50.             if (intentActivity != null) {  
  51.                
  52.             }  
  53.         }  
  54.     }  
  55.   
  56.     if (r.packageName != null) {  
  57.         ActivityStack topStack = getFocusedStack();  
  58.         ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);  
  59.         //待启动Activity所属的ActivityStack为当前focus的ActivityStack  
  60.         if (top != null && r.resultTo == null) {  
  61.             if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {  
  62.                   
  63.             }  
  64.         }  
  65.     } else {  
  66.   
  67.     }  
  68.     boolean newTask = false;  
  69.     boolean keepCurTransition = false;  
  70.   
  71.     if (r.resultTo == null && !addingToTask  
  72.             && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {  
  73.         targetStack = adjustStackFocus(r);  
  74.         moveHomeStack(targetStack.isHomeStack());  
  75.         if (reuseTask == null) {  
  76.             r.setTask(targetStack.createTaskRecord(getNextTaskId(),  
  77.                     newTaskInfo != null ? newTaskInfo : r.info,  
  78.                     newTaskIntent != null ? newTaskIntent : intent,  
  79.                     true), nulltrue);  
  80.             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +  
  81.                     r.task);  
  82.         } else {  
  83.   
  84.         }  
  85.         newTask = true;  
  86.         if (!movedHome) {  
  87.             if ((launchFlags &  
  88.                     (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))  
  89.                     == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {  
  90.   
  91.             }  
  92.         }  
  93.     } else if (sourceRecord != null) {  
  94.   
  95.     } else {  
  96.   
  97.     }  
  98.   
  99.     targetStack.mLastPausedActivity = null;  
  100.     targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);  
  101.     mService.setFocusedActivityLocked(r);  
  102.     return ActivityManager.START_SUCCESS;  
  103. }  

startActivityUncheckedLocked根据系统的状态、Intent设置的flag以及待启动Activity的属性等分为很多种case,我们先只关注启动launcher的流程。这里的targetStack就是mHomeStack,调用它的createTaskRecord方法创建一个新的TaskRecord对象并设置给新的ActivityRecord,一个TaskRecord对象表示一个新的任务,一个任务由一组Activity来共同组成。先来看创建TaskRecord的代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {  
  2.     TaskRecord task = new TaskRecord(taskId, info, intent);  
  3.     addTask(task, toTop);  
  4.     return task;  
  5. }  
  6.   
  7. TaskRecord(int _taskId, ActivityInfo info, Intent _intent) {  
  8.     taskId = _taskId;  
  9.     affinity = info.taskAffinity;  
  10.     setIntent(_intent, info);  
  11. }  
  12.   
  13. void setIntent(Intent _intent, ActivityInfo info) {  
  14.     stringName = null;  
  15.     if (info.targetActivity == null) {  
  16.   
  17.     } else {  
  18.         ComponentName targetComponent = new ComponentName(  
  19.                 info.packageName, info.targetActivity);  
  20.         if (_intent != null) {  
  21.             Intent targetIntent = new Intent(_intent);  
  22.             targetIntent.setComponent(targetComponent);  
  23.             targetIntent.setSelector(null);  
  24.             targetIntent.setSourceBounds(null);  
  25.             if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,  
  26.                     "Setting Intent of " + this + " to target " + targetIntent);  
  27.             intent = targetIntent;  
  28.             realActivity = targetComponent;  
  29.             origActivity = _intent.getComponent();  
  30.         } else {  
  31.             intent = null;  
  32.             realActivity = targetComponent;  
  33.             origActivity = new ComponentName(info.packageName, info.name);  
  34.         }  
  35.     }  
  36.     if (intent != null &&  
  37.             (intent.getFlags()&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {  
  38.   
  39.     }  
  40.     if (info.applicationInfo != null) {  
  41.         userId = UserHandle.getUserId(info.applicationInfo.uid);  
  42.     }  
  43. }  
  44.   
  45. void addTask(final TaskRecord task, final boolean toTop) {  
  46.     task.stack = this;  
  47.     if (toTop) {  
  48.         insertTaskAtTop(task);  
  49.     } else {  
  50.         mTaskHistory.add(0, task);  
  51.     }  
  52. }  
  53.   
  54. private void insertTaskAtTop(TaskRecord task) {  
  55.     ActivityStack lastStack = mStackSupervisor.getLastStack();  
  56.     final boolean fromHome = lastStack == null ? true : lastStack.isHomeStack();  
  57.     if (!isHomeStack() && (fromHome || topTask() != task)) {  
  58.         task.mOnTopOfHome = fromHome;  
  59.     }  
  60.     mTaskHistory.remove(task);  
  61.     int stackNdx = mTaskHistory.size();  
  62.     if (task.userId != mCurrentUser) {  
  63.         // Put non-current user tasks below current user tasks.  
  64.         while (--stackNdx >= 0) {  
  65.             if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {  
  66.                 break;  
  67.             }  
  68.         }  
  69.         ++stackNdx;  
  70.     }  
  71.     mTaskHistory.add(stackNdx, task);  
  72. }  

上面的代码都比较简单,首先构造TaskRecord,并把它添加到mTaskHistory数组中。接下来调用ActivityRecord的setTask把待启动的Activity绑定到此TaskRecord上:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {  
  2.     if (task != null && task.removeActivity(this)) {  
  3.   
  4.     }  
  5.     if (inHistory && !finishing) {  
  6.   
  7.     }  
  8.     if (newThumbHolder == null) {  
  9.         newThumbHolder = newTask;  
  10.     }  
  11.     task = newTask;  
  12.     if (!isRoot && (intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {  
  13.   
  14.     } else {  
  15.         thumbHolder = newThumbHolder;  
  16.     }  
  17. }  

接下来在startActivityUncheckedLocked调用ActivityStack的startActivityLocked方法来启动这个Activity:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final void startActivityLocked(ActivityRecord r, boolean newTask,  
  2.         boolean doResume, boolean keepCurTransition, Bundle options) {  
  3.     TaskRecord rTask = r.task;  
  4.     final int taskId = rTask.taskId;  
  5.     if (taskForIdLocked(taskId) == null || newTask) {  
  6.   
  7.     }  
  8.     TaskRecord task = null;  
  9.     if (!newTask) {  
  10.   
  11.     }  
  12.   
  13.     if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {  
  14.   
  15.     }  
  16.     task = r.task;  
  17.     task.addActivityToTop(r);  
  18.     r.putInHistory();  
  19.     r.frontOfTask = newTask;  
  20.     if (!isHomeStack() || numActivities() > 0) {  
  21.         boolean showStartingIcon = newTask;  
  22.         ProcessRecord proc = r.app;  
  23.         if (proc == null) {  
  24.             proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);  
  25.         }  
  26.         if (proc == null || proc.thread == null) {  
  27.             showStartingIcon = true;  
  28.         }  
  29.   
  30.         if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {  
  31.   
  32.         } else {  
  33.             mWindowManager.prepareAppTransition(newTask  
  34.                     ? AppTransition.TRANSIT_TASK_OPEN  
  35.                     : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);  
  36.             mNoAnimActivities.remove(r);  
  37.         }  
  38.         r.updateOptionsLocked(options);  
  39.         mWindowManager.addAppToken(task.mActivities.indexOf(r),  
  40.                 r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,  
  41.                 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,  
  42.                 r.info.configChanges);  
  43.         boolean doShow = true;  
  44.         if (newTask) {  
  45.             if ((r.intent.getFlags()  
  46.                     &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {  
  47.   
  48.             }  
  49.         }  
  50.         if (SHOW_APP_STARTING_PREVIEW && doShow) {  
  51.             ActivityRecord prev = mResumedActivity;  
  52.             if (prev != null) {  
  53.   
  54.             }  
  55.             mWindowManager.setAppStartingWindow(  
  56.                     r.appToken, r.packageName, r.theme,  
  57.                     mService.compatibilityInfoForPackageLocked(  
  58.                             r.info.applicationInfo), r.nonLocalizedLabel,  
  59.                     r.labelRes, r.icon, r.logo, r.windowFlags,  
  60.                     prev != null ? prev.appToken : null, showStartingIcon);  
  61.         }  
  62.     } else {  
  63.   
  64.     }  
  65.     if (VALIDATE_TOKENS) {  
  66.         validateAppTokensLocked();  
  67.     }  
  68.     if (doResume) {  
  69.         mStackSupervisor.resumeTopActivitiesLocked();  
  70.     }  
  71. }  

在ActivityStack的startActivityLocked方法中,首先把新的ActivityRecord添加到TaskRecord的mActivities数组中,表示当前task包含此Activity。接下来调用WMS的prepareAppTransition、addAppToken和setAppStartingWindow接口为Activity的切换做准备,关于WMS的内容,我们后面再来介绍。最后调用mStackSupervisor.resumeTopActivitiesLocked去启动Activity:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. boolean resumeTopActivitiesLocked() {  
  2.     return resumeTopActivitiesLocked(nullnullnull);  
  3. }  
  4. boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,  
  5.         Bundle targetOptions) {  
  6.     if (targetStack == null) {  
  7.         targetStack = getFocusedStack();  
  8.     }  
  9.     boolean result = false;  
  10.     for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {  
  11.         final ActivityStack stack = mStacks.get(stackNdx);  
  12.         if (isFrontStack(stack)) {  
  13.             if (stack == targetStack) {  
  14.                 result = stack.resumeTopActivityLocked(target, targetOptions);  
  15.             } else {  
  16.                 stack.resumeTopActivityLocked(null);  
  17.             }  
  18.         }  
  19.     }  
  20.     return result;  
  21. }  

这里会再次调用到ActivityStack的resumeTopActivityLocked去完成Activity的启动:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {  
  2.     ActivityRecord next = topRunningActivityLocked(null);  
  3.   
  4.     final boolean userLeaving = mStackSupervisor.mUserLeaving;  
  5.     mStackSupervisor.mUserLeaving = false;  
  6.     if (next == null) {  
  7.   
  8.     }  
  9.     next.delayedResume = false;  
  10.     if (mResumedActivity == next && next.state == ActivityState.RESUMED &&  
  11.                 mStackSupervisor.allResumedActivitiesComplete()) {  
  12.   
  13.     }  
  14.     final TaskRecord nextTask = next.task;  
  15.     final TaskRecord prevTask = prev != null ? prev.task : null;  
  16.     if (prevTask != null && prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) {  
  17.   
  18.     }  
  19.   
  20.     if (mService.isSleepingOrShuttingDown()  
  21.             && mLastPausedActivity == next  
  22.             && mStackSupervisor.allPausedActivitiesComplete()) {  
  23.   
  24.     }  
  25.   
  26.     mStackSupervisor.mStoppingActivities.remove(next);  
  27.     mStackSupervisor.mGoingToSleepActivities.remove(next);  
  28.     next.sleeping = false;  
  29.     mStackSupervisor.mWaitingVisibleActivities.remove(next);  
  30.     next.updateOptionsLocked(options);  
  31.   
  32.     if (!mStackSupervisor.allPausedActivitiesComplete()) {  
  33.   
  34.     }  
  35.   
  36.     boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);  
  37.     if (mResumedActivity != null) {  
  38.         pausing = true;  
  39.         startPausingLocked(userLeaving, false);  
  40.         if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);  
  41.     }  
  42.     if (pausing) {  
  43.   
  44.     }  
  45.   
  46.     if (mService.mSleeping && mLastNoHistoryActivity != null &&  
  47.             !mLastNoHistoryActivity.finishing) {  
  48.   
  49.     }  
  50.     if (prev != null && prev != next) {  
  51.   
  52.     }  
  53.     // Launching this app's activity, make sure the app is no longer  
  54.     // considered stopped.  
  55.     try {  
  56.         AppGlobals.getPackageManager().setPackageStoppedState(  
  57.                 next.packageName, false, next.userId); /* TODO: Verify if correct userid */  
  58.     } catch (RemoteException e1) {  
  59.     } catch (IllegalArgumentException e) {  
  60.         Slog.w(TAG, "Failed trying to unstop package "  
  61.                 + next.packageName + ": " + e);  
  62.     }  
  63.   
  64.     boolean anim = true;  
  65.     if (prev != null) {  
  66.   
  67.     } else {  
  68.         if (mNoAnimActivities.contains(next)) {  
  69.             anim = false;  
  70.             mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);  
  71.         } else {  
  72.             mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);  
  73.         }  
  74.     }  
  75.     if (anim) {  
  76.         next.applyOptionsLocked();  
  77.     } else {  
  78.         next.clearOptionsLocked();  
  79.     }  
  80.     ActivityStack lastStack = mStackSupervisor.getLastStack();  
  81.     if (next.app != null && next.app.thread != null) {  
  82.   
  83.     } else {  
  84.         // Whoops, need to restart this activity!  
  85.         if (!next.hasBeenLaunched) {  
  86.             next.hasBeenLaunched = true;  
  87.         } else {  
  88.             if (SHOW_APP_STARTING_PREVIEW) {  
  89.   
  90.             }  
  91.             if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);  
  92.         }  
  93.         if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);  
  94.         mStackSupervisor.startSpecificActivityLocked(next, truetrue);  
  95.     }  
  96.     if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();  
  97.     return true;  
  98. }  

此时topRunningActivityLocked()中返回launcher所代表的的ActivityRecord对象,并最终调用mStackSupervisor.startSpecificActivityLocked去启动Activity:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void startSpecificActivityLocked(ActivityRecord r,  
  2.         boolean andResume, boolean checkConfig) {  
  3.     ProcessRecord app = mService.getProcessRecordLocked(r.processName,  
  4.             r.info.applicationInfo.uid, true);  
  5.     r.task.stack.setLaunchTime(r);  
  6.     if (app != null && app.thread != null) {  
  7.   
  8.     }  
  9.     mService.startProcessLocked(r.processName, r.info.applicationInfo, true0,  
  10.             "activity", r.intent.getComponent(), falsefalsetrue);  
  11. }  
  12.   
  13. final ProcessRecord startProcessLocked(String processName,  
  14.         ApplicationInfo info, boolean knownToBeDead, int intentFlags,  
  15.         String hostingType, ComponentName hostingName, boolean allowWhileBooting,  
  16.         boolean isolated, boolean keepIfLarge) {  
  17.     ProcessRecord app;  
  18.     if (!isolated) {  
  19.         app = getProcessRecordLocked(processName, info.uid, keepIfLarge);  
  20.     } else {  
  21.         app = null;  
  22.     }  
  23.   
  24.     if (app != null && app.pid > 0) {  
  25.   
  26.     }  
  27.     String hostingNameStr = hostingName != null  
  28.             ? hostingName.flattenToShortString() : null;  
  29.   
  30.     if (app == null) {  
  31.         app = newProcessRecordLocked(info, processName, isolated);  
  32.         mProcessNames.put(processName, app.uid, app);  
  33.         }  
  34.     } else {  
  35.   
  36.     }  
  37.   
  38.     startProcessLocked(app, hostingType, hostingNameStr);  
  39.     return (app.pid != 0) ? app : null;  
  40. }  

因为launcher的Process并没有创建,所以也没有它的ProcessRecord对象存在,这里首先创建一个ProcessRecord对象,并调用startProcessLocked通过Zygote去fork一个进程,并把进程的pid号保存在ProcessRecord.pid里。关于Zygote如何fork一个进程,我们这里先不关注了,fork进程完后,就会执行到ActivityThread的main方法,我们从这里开始分析:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) {  
  2.     SamplingProfilerIntegration.start();  
  3.     CloseGuard.setEnabled(false);  
  4.     Environment.initForCurrentUser();  
  5.     EventLogger.setReporter(new EventLoggingReporter());  
  6.     Security.addProvider(new AndroidKeyStoreProvider());  
  7.     Process.setArgV0("<pre-initialized>");  
  8.     Looper.prepareMainLooper();  
  9.     ActivityThread thread = new ActivityThread();  
  10.     thread.attach(false);  
  11.     if (sMainThreadHandler == null) {  
  12.         sMainThreadHandler = thread.getHandler();  
  13.     }  
  14.     AsyncTask.init();  
  15.     Looper.loop();  
  16.     throw new RuntimeException("Main thread loop unexpectedly exited");  
  17. }  

这里首先初始化一些环境,然后调用ActivtityThread自身的attach方法,并最终开始looper循环。前面在介绍AMS启动的时候,也会构造ActivityThread对象,但它调用attach方法传入的参数为true,表示为system的进程,我们这里传入的参数为false:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void attach(boolean system) {  
  2.     sCurrentActivityThread = this;  
  3.     mSystemThread = system;  
  4.     if (!system) {  
  5.         ViewRootImpl.addFirstDrawHandler(new Runnable() {  
  6.             @Override  
  7.             public void run() {  
  8.                 ensureJitEnabled();  
  9.             }  
  10.         });  
  11.         android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",  
  12.                                                 UserHandle.myUserId());  
  13.         RuntimeInit.setApplicationObject(mAppThread.asBinder());  
  14.         IActivityManager mgr = ActivityManagerNative.getDefault();  
  15.         try {  
  16.             mgr.attachApplication(mAppThread);  
  17.         } catch (RemoteException ex) {  
  18.             // Ignore  
  19.         }  
  20.     } else {  
  21.   
  22.     }  
  23.     ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {  
  24.         @Override  
  25.         public void onConfigurationChanged(Configuration newConfig) {  
  26.             synchronized (mResourcesManager) {  
  27.                 // We need to apply this change to the resources  
  28.                 // immediately, because upon returning the view  
  29.                 // hierarchy will be informed about it.  
  30.                 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {  
  31.                     // This actually changed the resources!  Tell  
  32.                     // everyone about it.  
  33.                     if (mPendingConfiguration == null ||  
  34.                             mPendingConfiguration.isOtherSeqNewer(newConfig)) {  
  35.                         mPendingConfiguration = newConfig;  
  36.                           
  37.                         sendMessage(H.CONFIGURATION_CHANGED, newConfig);  
  38.                     }  
  39.                 }  
  40.             }  
  41.         }  
  42.         @Override  
  43.         public void onLowMemory() {  
  44.         }  
  45.         @Override  
  46.         public void onTrimMemory(int level) {  
  47.         }  
  48.     });  
  49. }  

在attach方法中,首先设置进程名字,这个名字只是在启动过程中显示。然后调用AMS的attachApplication方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.     private final boolean attachApplicationLocked(IApplicationThread thread,  
  2.             int pid) {  
  3.         ProcessRecord app;  
  4.         if (pid != MY_PID && pid >= 0) {  
  5.             synchronized (mPidsSelfLocked) {  
  6.                 app = mPidsSelfLocked.get(pid);  
  7.             }  
  8.         } else {  
  9.             app = null;  
  10.         }  
  11.   
  12.         final String processName = app.processName;  
  13.         try {  
  14.             AppDeathRecipient adr = new AppDeathRecipient(  
  15.                     app, pid, thread);  
  16.             thread.asBinder().linkToDeath(adr, 0);  
  17.             app.deathRecipient = adr;  
  18.         } catch (RemoteException e) {  
  19.             app.resetPackageList(mProcessStats);  
  20.             startProcessLocked(app, "link fail", processName);  
  21.             return false;  
  22.         }  
  23.   
  24.         app.makeActive(thread, mProcessStats);  
  25.         app.curAdj = app.setAdj = -100;  
  26.         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;  
  27.         app.forcingToForeground = null;  
  28.         app.foregroundServices = false;  
  29.         app.hasShownUi = false;  
  30.         app.debugging = false;  
  31.         app.cached = false;  
  32.         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);  
  33.         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);  
  34.         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;  
  35.   
  36.         try {  
  37.   
  38.             String profileFile = app.instrumentationProfileFile;  
  39.             ParcelFileDescriptor profileFd = null;  
  40.             boolean profileAutoStop = false;  
  41.   
  42.             boolean enableOpenGlTrace = false;  
  43.   
  44.             boolean isRestrictedBackupMode = false;  
  45.   
  46.             ensurePackageDexOpt(app.instrumentationInfo != null  
  47.                     ? app.instrumentationInfo.packageName  
  48.                     : app.info.packageName);  
  49.   
  50.             ApplicationInfo appInfo = app.instrumentationInfo != null  
  51.                     ? app.instrumentationInfo : app.info;  
  52.             app.compat = compatibilityInfoForPackageLocked(appInfo);  
  53.             if (profileFd != null) {  
  54.                 profileFd = profileFd.dup();  
  55.             }  
  56.             thread.bindApplication(processName, appInfo, providers,  
  57.                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,  
  58.                     app.instrumentationArguments, app.instrumentationWatcher,  
  59.                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,  
  60.                     isRestrictedBackupMode || !normalMode, app.persistent,  
  61.                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),  
  62.                     mCoreSettingsObserver.getCoreSettingsLocked());  
  63.             updateLruProcessLocked(app, falsenull);  
  64.             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();  
  65.         } catch (Exception e) {  
  66.             app.resetPackageList(mProcessStats);  
  67.             app.unlinkDeathRecipient();  
  68.             startProcessLocked(app, "bind fail", processName);  
  69.             return false;  
  70.         }  
  71.           
  72.         mPersistentStartingProcesses.remove(app);  
  73.         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,  
  74.                 "Attach application locked removing on hold: " + app);  
  75.         mProcessesOnHold.remove(app);  
  76.         boolean badApp = false;  
  77.         boolean didSomething = false;  
  78.   
  79.         if (normalMode) {  
  80.             try {  
  81.                 if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) {  
  82.                     didSomething = true;  
  83.                 }  
  84.             } catch (Exception e) {  
  85.                 badApp = true;  
  86.             }  
  87.         }  
  88.   
  89.         if (!badApp) {  
  90.             try {  
  91.                 didSomething |= mServices.attachApplicationLocked(app, processName);  
  92.             } catch (Exception e) {  
  93.                 badApp = true;  
  94.             }  
  95.         }  
  96.   
  97.         if (!badApp && isPendingBroadcastProcessLocked(pid)) {  
  98.             try {  
  99.                 didSomething |= sendPendingBroadcastsLocked(app);  
  100.             } catch (Exception e) {  
  101.                 // If the app died trying to launch the receiver we declare it 'bad'  
  102.                 badApp = true;  
  103.             }  
  104.         }  
  105.   
  106.         if (!didSomething) {  
  107.             updateOomAdjLocked();  
  108.         }  
  109.         return true;  
  110. }  
  111.       

attachApplicationLocked函数比较长,首先调用ProcessRecord的makeActive方法调用ProcessStatsService开始记录process的状态。后面主要做了四件事情:一是调用ActivityThread的bindApplication方法去启动Application;二是调用StackSupervisor的attachApplicationLocked去启动ActivityStack栈顶的Activity;三是根据mPendingServices和mRestartingServices列表启动在当前application中的service;四是检查是否有广播broadcast到这个application,如果有则广播。后面两件事我们这里先不讨论,首先来看前面两个方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public final void bindApplication(String processName,  
  2.         ApplicationInfo appInfo, List<ProviderInfo> providers,  
  3.         ComponentName instrumentationName, String profileFile,  
  4.         ParcelFileDescriptor profileFd, boolean autoStopProfiler,  
  5.         Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,  
  6.         IUiAutomationConnection instrumentationUiConnection, int debugMode,  
  7.         boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,  
  8.         Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,  
  9.         Bundle coreSettings) {  
  10.     if (services != null) {  
  11.         // Setup the service cache in the ServiceManager  
  12.         ServiceManager.initServiceCache(services);  
  13.     }  
  14.     setCoreSettings(coreSettings);  
  15.     AppBindData data = new AppBindData();  
  16.     data.processName = processName;  
  17.     data.appInfo = appInfo;  
  18.     data.providers = providers;  
  19.     data.instrumentationName = instrumentationName;  
  20.     data.instrumentationArgs = instrumentationArgs;  
  21.     data.instrumentationWatcher = instrumentationWatcher;  
  22.     data.instrumentationUiAutomationConnection = instrumentationUiConnection;  
  23.     data.debugMode = debugMode;  
  24.     data.enableOpenGlTrace = enableOpenGlTrace;  
  25.     data.restrictedBackupMode = isRestrictedBackupMode;  
  26.     data.persistent = persistent;  
  27.     data.config = config;  
  28.     data.compatInfo = compatInfo;  
  29.     data.initProfileFile = profileFile;  
  30.     data.initProfileFd = profileFd;  
  31.     data.initAutoStopProfiler = false;  
  32.     sendMessage(H.BIND_APPLICATION, data);  
  33. }  

这里首先调用会给H handler发送两个消息,一个是SET_CORE_SETTINGS;另一个是BIND_APPLICATION。SET_CORE_SETTINGS主要是获取系统的设定并设置到ActivityThread中。BIND_APPLICATION用于启动Application并安装所有的provider,并回调Applicant的oncreate方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void handleBindApplication(AppBindData data) {  
  2.     mBoundApplication = data;  
  3.     mConfiguration = new Configuration(data.config);  
  4.     mCompatConfiguration = new Configuration(data.config);  
  5.     mProfiler = new Profiler();  
  6.     mProfiler.profileFile = data.initProfileFile;  
  7.     mProfiler.profileFd = data.initProfileFd;  
  8.     mProfiler.autoStopProfiler = data.initAutoStopProfiler;  
  9.   
  10.     Process.setArgV0(data.processName);  
  11.     android.ddm.DdmHandleAppName.setAppName(data.processName,  
  12.                                             UserHandle.myUserId());  
  13.   
  14.     TimeZone.setDefault(null);  
  15.     Locale.setDefault(data.config.locale);  
  16.     mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);  
  17.     mCurDefaultDisplayDpi = data.config.densityDpi;  
  18.     applyCompatConfiguration(mCurDefaultDisplayDpi);  
  19.     data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);  
  20.   
  21.     if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)  
  22.             == 0) {  
  23.         mDensityCompatMode = true;  
  24.         Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);  
  25.     }  
  26.     updateDefaultDensity();  
  27.     final ContextImpl appContext = new ContextImpl();  
  28.     appContext.init(data.info, nullthis);  
  29.     if (!Process.isIsolated()) {  
  30.         final File cacheDir = appContext.getCacheDir();  
  31.         if (cacheDir != null) {  
  32.             System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());  
  33.   
  34.             setupGraphicsSupport(data.info, cacheDir);  
  35.         } else {  
  36.             Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");  
  37.         }  
  38.     }  
  39.   
  40.     if ((data.appInfo.flags &  
  41.          (ApplicationInfo.FLAG_SYSTEM |  
  42.           ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {  
  43.         StrictMode.conditionallyEnableDebugLogging();  
  44.     }  
  45.   
  46.     if (data.appInfo.targetSdkVersion > 9) {  
  47.         StrictMode.enableDeathOnNetwork();  
  48.     }  
  49.   
  50.     if (data.enableOpenGlTrace) {  
  51.         GLUtils.setTracingLevel(1);  
  52.     }  
  53.   
  54.     boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;  
  55.     Trace.setAppTracingAllowed(appTracingAllowed);  
  56.   
  57.     if (data.instrumentationName != null) {  
  58.   
  59.     } else {  
  60.         mInstrumentation = new Instrumentation();  
  61.     }  
  62.     if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {  
  63.         dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();  
  64.     }  
  65.   
  66.     final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();  
  67.     try {  
  68.         Application app = data.info.makeApplication(data.restrictedBackupMode, null);  
  69.         mInitialApplication = app;  
  70.         if (!data.restrictedBackupMode) {  
  71.             List<ProviderInfo> providers = data.providers;  
  72.             if (providers != null) {  
  73.                 installContentProviders(app, providers);  
  74.                 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);  
  75.             }  
  76.         }  
  77.   
  78.         try {  
  79.             mInstrumentation.onCreate(data.instrumentationArgs);  
  80.         }  
  81.         catch (Exception e) {  
  82.   
  83.         }  
  84.         try {  
  85.             mInstrumentation.callApplicationOnCreate(app);  
  86.         } catch (Exception e) {  
  87.   
  88.         }  
  89.     } finally {  
  90.         StrictMode.setThreadPolicy(savedPolicy);  
  91.     }  
  92. }  

handleBindApplication中首先修改process的名字,然后恢复时区和位置信息。通过getPackageInfoNoCheck方法获取一个LoadedApk对象,并把packageName和LoadedApk添加到全局的mPackages中。在handleBindApplication中会构造整个application运行的context环境,并构造一个Instrumentation对象用于启动Activity。如果不是restrictedBackupMode模式,就调用installContentProviders去安装这个APK里面所有的provider,关于installContentProviders,前面在介绍安装systemProvider的时候已经讲解过了。最后调用mInstrumentation.callApplicationOnCreate去回调Application的onCreate方法,如果在APK中有继承Applicantion的class,则回调对应class的oncreate方法。

attachApplicationLocked的第二件事情是调用StackSupervisor的attachApplicationLocked去启动ActivityStack栈顶的Activity:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {  
  2.     boolean didSomething = false;  
  3.     final String processName = app.processName;  
  4.     for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {  
  5.         final ActivityStack stack = mStacks.get(stackNdx);  
  6.         if (!isFrontStack(stack)) {  
  7.             continue;  
  8.         }  
  9.         ActivityRecord hr = stack.topRunningActivityLocked(null);  
  10.         if (hr != null) {  
  11.             if (hr.app == null && app.uid == hr.info.applicationInfo.uid  
  12.                     && processName.equals(hr.processName)) {  
  13.                 try {  
  14.                     if (headless) {  
  15.   
  16.                     } else if (realStartActivityLocked(hr, app, truetrue)) {  
  17.                         didSomething = true;  
  18.                     }  
  19.                 } catch (Exception e) {  
  20.                     Slog.w(TAG, "Exception in new application when starting activity "  
  21.                           + hr.intent.getComponent().flattenToShortString(), e);  
  22.                     throw e;  
  23.                 }  
  24.             }  
  25.         }  
  26.     }  
  27.     if (!didSomething) {  
  28.         ensureActivitiesVisibleLocked(null0);  
  29.     }  
  30.     return didSomething;  
  31. }  

attachApplicationLocked从ActivityTask中的TaskRecord列表中获取处于栈顶的ActivityRecord对象,也就是我们要启动的launcher。然后调用realStartActivityLocked方法去完成启动:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final boolean realStartActivityLocked(ActivityRecord r,  
  2.         ProcessRecord app, boolean andResume, boolean checkConfig)  
  3.         throws RemoteException {  
  4.     r.startFreezingScreenLocked(app, 0);  
  5.     mWindowManager.setAppVisibility(r.appToken, true);  
  6.     r.startLaunchTickingLocked();  
  7.   
  8.     if (checkConfig) {  
  9.         Configuration config = mWindowManager.updateOrientationFromAppTokens(  
  10.                 mService.mConfiguration,  
  11.                 r.mayFreezeScreenLocked(app) ? r.appToken : null);  
  12.         mService.updateConfigurationLocked(config, r, falsefalse);  
  13.     }  
  14.     r.app = app;  
  15.     app.waitingToKill = null;  
  16.     r.launchCount++;  
  17.     r.lastLaunchTime = SystemClock.uptimeMillis();  
  18.   
  19.     int idx = app.activities.indexOf(r);  
  20.     if (idx < 0) {  
  21.         app.activities.add(r);  
  22.     }  
  23.     mService.updateLruProcessLocked(app, truenull);  
  24.     mService.updateOomAdjLocked();  
  25.     final ActivityStack stack = r.task.stack;  
  26.     try {  
  27.         if (app.thread == null) {  
  28.             throw new RemoteException();  
  29.         }  
  30.         List<ResultInfo> results = null;  
  31.         List<Intent> newIntents = null;  
  32.         if (andResume) {  
  33.             results = r.results;  
  34.             newIntents = r.newIntents;  
  35.         }  
  36.   
  37.         if (r.isHomeActivity() && r.isNotResolverActivity()) {  
  38.             mService.mHomeProcess = r.task.mActivities.get(0).app;  
  39.         }  
  40.         mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());  
  41.         r.sleeping = false;  
  42.         r.forceNewConfig = false;  
  43.         mService.showAskCompatModeDialogLocked(r);  
  44.         r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);  
  45.         String profileFile = null;  
  46.         ParcelFileDescriptor profileFd = null;  
  47.         boolean profileAutoStop = false;  
  48.   
  49.         app.hasShownUi = true;  
  50.         app.pendingUiClean = true;  
  51.   
  52.         app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);  
  53.         app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,  
  54.                 System.identityHashCode(r), r.info,  
  55.                 new Configuration(mService.mConfiguration), r.compat,  
  56.                 app.repProcState, r.icicle, results, newIntents, !andResume,  
  57.                 mService.isNextTransitionForward(), profileFile, profileFd,  
  58.                 profileAutoStop);  
  59.   
  60.     r.launchFailed = false;  
  61.     if (stack.updateLRUListLocked(r)) {  
  62.   
  63.     }  
  64.     if (andResume) {  
  65.   
  66.         stack.minimalResumeActivityLocked(r);  
  67.     } else {  
  68.         r.state = ActivityState.STOPPED;  
  69.         r.stopped = true;  
  70.     }  
  71.     return true;  

realStartActivityLocked方法中首先记录Activity启动时间和状态,最终调用ActivityThread的scheduleLaunchActivity去启动Activity。scheduleLaunchActivity方法中,通过传入的参数构造一个ActivityClientRecord,并发送LAUNCH_ACTIVITY消息给H handler,并最终调用handleLaunchActivity方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.     unscheduleGcIdler();  
  3.       
  4.     Activity a = performLaunchActivity(r, customIntent);  
  5.     if (a != null) {  
  6.         r.createdConfig = new Configuration(mConfiguration);  
  7.         Bundle oldState = r.state;  
  8.         handleResumeActivity(r.token, false, r.isForward,  
  9.                 !r.activity.mFinished && !r.startsNotResumed);  
  10.         if (!r.activity.mFinished && r.startsNotResumed) {  
  11.   
  12.         }  
  13.     } else {  
  14.   
  15.     }  
  16. }  

在handleLaunchActivity中主要执行两个步骤,一是performLaunchActivity,这个方法用于加载对象Activity的class文件,并且实例化一个Activity对象,调用createBaseContextForActivity去创建一个ContextImpl对象并attach上这个Activity。最后通过mInstrumentation回调Activity的OnCreate、OnStart、OnRestoreInstanceState、OnPostCreate这几个方法,并把ActivityClientRecord对象加入到ActivityThread的mActivities数组;二是调用handleResumeActivity回调Activity的OnResume方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,  
  2.         boolean reallyResume) {  
  3.     unscheduleGcIdler();  
  4.     ActivityClientRecord r = performResumeActivity(token, clearHide);  
  5.     if (r != null) {  
  6.         final Activity a = r.activity;  
  7.         final int forwardBit = isForward ?  
  8.                 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;  
  9.         boolean willBeVisible = !a.mStartedActivity;  
  10.         if (!willBeVisible) {  
  11.             try {  
  12.                 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(  
  13.                         a.getActivityToken());  
  14.             } catch (RemoteException e) {  
  15.             }  
  16.         }  
  17.         if (r.window == null && !a.mFinished && willBeVisible) {  
  18.             r.window = r.activity.getWindow();  
  19.             View decor = r.window.getDecorView();  
  20.             decor.setVisibility(View.INVISIBLE);  
  21.             ViewManager wm = a.getWindowManager();  
  22.             WindowManager.LayoutParams l = r.window.getAttributes();  
  23.             a.mDecor = decor;  
  24.             l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;  
  25.             l.softInputMode |= forwardBit;  
  26.             if (a.mVisibleFromClient) {  
  27.                 a.mWindowAdded = true;  
  28.                 wm.addView(decor, l);  
  29.             }  
  30.   
  31.         } else if (!willBeVisible) {  
  32.             if (localLOGV) Slog.v(  
  33.                 TAG, "Launch " + r + " mStartedActivity set");  
  34.             r.hideForNow = true;  
  35.         }  
  36.         cleanUpPendingRemoveWindows(r);  
  37.         if (!r.activity.mFinished && willBeVisible  
  38.                 && r.activity.mDecor != null && !r.hideForNow) {  
  39.             WindowManager.LayoutParams l = r.window.getAttributes();  
  40.             if ((l.softInputMode  
  41.                     & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)  
  42.                     != forwardBit) {  
  43.                 l.softInputMode = (l.softInputMode  
  44.                         & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))  
  45.                         | forwardBit;  
  46.                 if (r.activity.mVisibleFromClient) {  
  47.                     ViewManager wm = a.getWindowManager();  
  48.                     View decor = r.window.getDecorView();  
  49.                     wm.updateViewLayout(decor, l);  
  50.                 }  
  51.             }  
  52.             r.activity.mVisibleFromServer = true;  
  53.             mNumVisibleActivities++;  
  54.             if (r.activity.mVisibleFromClient) {  
  55.                 r.activity.makeVisible();  
  56.             }  
  57.         }  
  58.         if (!r.onlyLocalRequest) {  
  59.             r.nextIdle = mNewActivities;  
  60.             mNewActivities = r;  
  61.             if (localLOGV) Slog.v(  
  62.                 TAG, "Scheduling idle handler for " + r);  
  63.             Looper.myQueue().addIdleHandler(new Idler());  
  64.         }  
  65.         r.onlyLocalRequest = false;  
  66.         // Tell the activity manager we have resumed.  
  67.         if (reallyResume) {  
  68.             try {  
  69.                 ActivityManagerNative.getDefault().activityResumed(token);  
  70.             } catch (RemoteException ex) {  
  71.             }  
  72.         }  
  73.     } else {  
  74.   
  75.     }  

handleResumeActivity调用performResumeActivity回调activity的performResume方法,并调用WMS的方法让这个Activity显示出来。并且向ActivityThread所在的Looper注册IdleHandler,用于在Activtiy处理空闲的时候回调。到这里启动launcher的流程就介绍完了。

关于TaskRecord、ProcessRecord、ActivityRecord和ActvityStack的关系如下,我们在下一节介绍启动一个应用的时候再来具体分析。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值