zoukankan      html  css  js  c++  java
  • AMS分析 -- 启动过程

    一. AMS简介

       AmS可以说是Android上层系统最核心的模块之一,其主要完成管理应用进程的生命周期以及进程的Activity,Service,Broadcast和Provider等。

       从系统运行的角度看,AmS可以分为Client端和Service端:

                 Client端运行在各个app进程,app进程实现了具体的 Activity,Service等,告诉系统我有那些Activity,Service等,并且调用系统接口来完成显示;

                 Service端运行在 SystemServer进程,是系统级别的ActivityManagerService的具体实现,其响应Client端的系统调用请求,并且管理 Client端各个app进程的生命周期。

       

                                                             图1 AmS基本类图

        关于AMS的代理模式可以参考 http://www.cnblogs.com/neo-java/p/7230042.html

         如下图是AmS内部主要数据结构类图,看了code相信大家都会知道这些类都是干什么的,这儿只是总结一下。

      

                                                               图2  AmS内部主要数据结构类图

    二. AMS启动过程

     启动过程主要分为四部分:

    1、创建出SystemServer进程的Android运行环境。
    在这一部分,SystemServer进程主要创建出对应的ActivityThread和ContextImpl,构成Android运行环境。
    AMS的后续工作依赖于SystemServer在此创建出的运行环境。

    2、完成AMS的初始化和启动。
    在这一部分,单纯地调用AMS的构造函数和start函数,完成AMS的一些初始化工作。

    3、将SystemServer进程纳入到AMS的管理体系中。
    AMS作为Java世界的进程管理和调度中心,要对所有Java进程一视同仁,因此SystemServer进程也必须被AMS管理。
    在这个过程中,AMS加载了SystemServer中framework-res.apk的信息,并启动和注册了SettingsProvider.apk。

    4、开始执行AMS启动完毕后才能进行的工作。
    系统中的一些服务和进程,必须等待AMS完成启动后,才能展开后续工作。
    在这一部分,AMS通过调用systemReady函数,通知系统中的其它服务和进程,可以进行对应工作了。
    在这个过程中,值得我们关注的是:Home Activity被启动了。当该Activity被加载完成后,最终会触发ACTION_BOOT_COMPLETED广播。

    下面分别讲解。

     2.1 创建SystemServer进程的Android运行环境 

    2.1.1  我们已经知道了,zygote创建出的第一个java进程是SystemServer。
              在SystemServer的run函数中,在启动AMS之前,调用了createSystemContext函数。

    其代码如下所示:

     1 .............
     2 //SystemServer在启动任何服务之前,就调用了createSystemContext
     3 //创建出的Context保存在mSystemContext中
     4 // Initialize the system context.
     5 createSystemContext();
     6 
     7 // Create the system service manager.
     8 //SystemServiceManager负责启动所有的系统服务,使用的Context就是mSystemContext
     9 mSystemServiceManager = new SystemServiceManager(mSystemContext);
    10 .............

    我们跟进一下createSystemContext:

     1 private void createSystemContext() {
     2     //调用ActivityThread的systemMain函数,其中会创建出系统对应的Context对象
     3     ActivityThread activityThread = ActivityThread.systemMain();
     4 
     5     //取出上面函数创建的Context对象,保存在mSystemContext中
     6     mSystemContext = activityThread.getSystemContext();
     7 
     8     //设置系统主题
     9     mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    10 }

    以上函数中,最重要的就是ActivityThread.systemMain了,我们分析一下该函数。

    2.1.2 ActivityThread.systemMain的代码如下

     1 public static ActivityThread systemMain() {
     2     // The system process on low-memory devices do not get to use hardware
     3     // accelerated drawing, since this can add too much overhead to the
     4     // process.
     5     if (!ActivityManager.isHighEndGfx()) {
     6         //虽然写着ActivityManager,但和AMS没有任何关系
     7         //就是利用系统属性和配置信息进行判断
     8 
     9         //关闭硬件渲染功能
    10         ThreadedRenderer.disable(true);
    11     } else {
    12         ThreadedRenderer.enableForegroundTrimming();
    13     }
    14 
    15     //创建ActivityThread
    16     ActivityThread thread = new ActivityThread();
    17     //调用attach函数,参数为true
    18     thread.attach(true);
    19     return thread;
    20 }

    从上面的代码可以看出,ActivityThread的systemMain函数中,除了进行是否开启硬件渲染的判断外,主要作用是:
    创建出ActivityThread对象,然后调用该对象的attach函数。

    ActivityThread的构造函数比较简单:

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

    比较关键的是它的成员变量:

     1 ..........
     2 //定义了AMS与应用通信的接口
     3 final ApplicationThread mAppThread = new ApplicationThread();
     4 
     5 //拥有自己的looper,说明ActivityThread确实可以代表事件处理线程
     6 final Looper mLooper = Looper.myLooper();
     7 
     8 //H继承Handler,ActivityThread中大量事件处理依赖此Handler
     9 final H mH = new H();
    10 
    11 //用于保存该进程的ActivityRecord
    12 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>()
    13 ..........
    14 //用于保存进程中的Service
    15 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
    16 ...........
    17 //用于保存进程中的Application
    18 final ArrayList<Application> mAllApplications = new ArrayList<Application>();
    19 ...........

    我们需要知道的是,ActivityThread是android Framework中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。
    在Android中,应用进程指那些运行APK的进程,它们由zygote fork出来,其中运行着独立的dalvik虚拟机。
    与应用进程相对的就是系统进程,例如zygote和SystemServer。

     注意到此处的ActivityThread创建于SystemServer进程中。
    由于SystemServer中也运行着一些系统APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以认为SystemServer是一个特殊的应用进程。

    对于上面提到的ActivityThread的成员变量,其用途基本上可以从名称中得知,这里仅说明一下ApplicationThread。

    AMS负责管理和调度进程,因此AMS需要通过Binder机制和应用进程通信。
    为此,Android提供了一个IApplicationThread接口,该接口定义了AMS和应用进程之间的交互函数。

    如上图所示,ActivityThread作为应用进程的主线程代表,在其中持有ApplicationThread。ApplicationThread继承ApplicationThreadNative。
    当AMS与应用进程通信时,ApplicationThread将作为Binder通信的服务端。

     AMS与应用进程通信时,通过ApplicationThreadNative获取应用进程对应的ApplicationThreadProxy对象。
    通过ApplicationThreadProxy对象,将调用信息通过Binder传递到ActivityThread中的ApplicationThread。
    这个调用过程,今后还会遇到,碰到的时候再详细分析。

    2.1.3 ActivityThread.attach

     1 我们看看ActivityThread的attach函数:
     2 
     3 //此时,我们传入的参数为true,表示该ActivityThread是系统进程的ActivityThread
     4 private void attach(boolean system) {
     5     //创建出的ActivityThread保存在类的静态变量sCurrentActivityThread
     6     //AMS中的大量操作将会依赖于这个ActivityThread
     7     sCurrentActivityThread = this;
     8     mSystemThread = system;
     9 
    10     if (!system) {
    11         //应用进程的处理流程
    12         ..........
    13     } else { 
    14         //系统进程的处理流程,该情况只在SystemServer中处理
    15 
    16         // Don't set application object here -- if the system crashes,
    17         // we can't display an alert, we just want to die die die.
    18         //设置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer进程的名称为“system_process”
    19         android.ddm.DdmHandleAppName.setAppName("system_process",
    20                 UserHandle.myUserId());
    21 
    22         try {
    23             //创建ActivityThread中的重要成员:Instrumentation、Application和Context
    24             mInstrumentation = new Instrumentation();
    25             ContextImpl context = ContextImpl.createAppContext(
    26                         this, getSystemContext().mPackageInfo);
    27             mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    28             mInitialApplication.onCreate();
    29         } catch (Exception e) {
    30             throw new RuntimeException(
    31                     "Unable to instantiate Application():" + e.toString(), e);
    32         }
    33     }
    34 
    35     //以下系统进程和非系统进程均会执行
    36     ................
    37     //注册Configuration变化的回调通知
    38     ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
    39         @Override
    40         public void onConfigurationChanged(Configuration newConfig) {
    41             //当系统配置发生变化时(例如系统语言发生变化),回调该接口
    42             ...............
    43         }
    44         .............
    45     });
    46 }

    从上面的代码可以看出,对于系统进程而言,ActivityThread的attach函数最重要的工作就是创建了Instrumentation、Application和Context。

     Instrumentation
    Instrumentation是Android中的一个工具类,当该类被启用时,它将优先于应用中其它的类被初始化。
    此时,系统先创建它,再通过它创建其它组件。

    此外,系统和应用组件之间的交互也将通过Instrumentation来传递。
    因此,Instrumentation就能监控系统和组件的交互情况了。

    实际使用时,可以创建该类的派生类进行相应的操作。
    这个类在介绍启动Activity的过程时还会碰到,此处不作展开。

     Context
    Context是Android中的一个抽象类,用于维护应用运行环境的全局信息。
    通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。

    ActivityThread的attach函数中,通过下面的代码创建出系统应用对应的Context:

    1 .......
    2 //ContextImpl是Context的实现类
    3 ContextImpl context = ContextImpl.createAppContext(
    4         this, getSystemContext().mPackageInfo);
    5 .......

    Application
    Android中Application类用于保存应用的全局状态。

    我们经常使用的Activity和Service均必须和具体的Application绑定在一起。
    通过上图的继承关系,每个具体的Activity和Service均被加入到Android运行环境中。

    在ActivityThread中,针对系统进程,通过下面的代码创建了初始的Application:

    1 ..............
    2 //调用LoadedApk的makeApplication函数
    3 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    4 
    5 //启动Application
    6 mInitialApplication.onCreate();
    7 .............. 

    我们看一下LoadedApk.makeApplication:

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

    从上面的代码不难看出,这部分主要是创建framework-res.apk对应的Application,然后调用它的onCreate函数,完成启动。

    第一步的总结
    至此,createSystemContext函数介绍完毕。

    当SystemServer调用createSystemContext完毕后:
    1、得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程;
    2、得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。

    在继续分析AMS之前,我们先停下来思考一下,为什么在启动所有的服务前,SystemServer先要调用createSystemContext?

     个人觉得《深入理解Android》对这个问题,解释的比较好,大致意思如下:
    Android努力构筑了一个自己的运行环境。
    在这个环境中,进程的概念被模糊化了。组件的运行及它们之间的交互均在该环境中实现。

     createSystemContext函数就是为SystemServer进程搭建一个和应用进程一样的Android运行环境。

    Android运行环境是构建在进程之上的,应用程序一般只和Android运行环境交互。
    基于同样的道理,SystemServer进程希望它内部运行的应用,
    也通过Android运行环境交互,因此才调用了createSystemContext函数。

    创建Android运行环境时,
    由于SystemServer的特殊性,调用了ActivityThread.systemMain函数;
    对于普通的应用程序,将在自己的主线程中调用ActivityThread.main函数。

    上图表示了进程的Android运行环境涉及的主要类之间的关系。
    其中的核心类是ContextImpl,通过它可以得到ContentResolver、系统资源、应用信息等。

     

     2.2 AMS的初始化和启动

    创建完Android运行环境后,SystemServer调用startBootstrapServices,其中就创建并启动了AMS:

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

    注意到上面的代码并没有直接启动AMS,而是启动AMS的内部类Lifecycle。
    这是迫不得已的做法,由于AMS并没有继承SystemService,因此不能通过SystemServiceManager的startService直接启动它。
    可以这样理解:内部类Lifecycle对于AMS而言,就像一个适配器一样,让AMS能够像SystemService一样被SystemServiceManager通过反射的方式启动。

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

    接下来我们分别看看AMS的构造函数和start函数。

    AMS的构造函数

      1 public ActivityManagerService(Context systemContext) {
      2     //AMS的运行上下文与SystemServer一致
      3     mContext = systemContext;
      4     ............
      5     //取出的是ActivityThread的静态变量sCurrentActivityThread
      6     //这意味着mSystemThread与SystemServer中的ActivityThread一致
      7     mSystemThread = ActivityThread.currentActivityThread();
      8     ............
      9     mHandlerThread = new ServiceThread(TAG,
     10             android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
     11     mHandlerThread.start();
     12     //处理AMS中消息的主力
     13     mHandler = new MainHandler(mHandlerThread.getLooper());
     14 
     15     //UiHandler对应于Android中的UiThread
     16     mUiHandler = new UiHandler();
     17 
     18     if (sKillHandler == null) {
     19         sKillThread = new ServiceThread(TAG + ":kill",
     20                 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
     21         sKillThread.start();
     22         //用于接收消息,杀死进程
     23         sKillHandler = new KillHandler(sKillThread.getLooper());
     24     }
     25 
     26     //创建两个BroadcastQueue,前台的超时时间为10s,后台的超时时间为60s
     27     mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
     28             "foreground", BROADCAST_FG_TIMEOUT, false);
     29     mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
     30             "background", BROADCAST_BG_TIMEOUT, true);
     31     mBroadcastQueues[0] = mFgBroadcastQueue;
     32     mBroadcastQueues[1] = mBgBroadcastQueue;
     33 
     34     //创建变量,用于存储信息
     35     mServices = new ActiveServices(this);
     36     mProviderMap = new ProviderMap(this);
     37     mAppErrors = new AppErrors(mContext, this);
     38 
     39     //这一部分,分析BatteryStatsService时提过,进行BSS的初始化
     40     File dataDir = Environment.getDataDirectory();
     41     File systemDir = new File(dataDir, "system");
     42     systemDir.mkdirs();
     43     mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
     44     mBatteryStatsService.getActiveStatistics().readLocked();
     45     mBatteryStatsService.scheduleWriteToDisk();
     46     mOnBattery = DEBUG_POWER ? true
     47             : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
     48     mBatteryStatsService.getActiveStatistics().setCallback(this);
     49 
     50     //创建ProcessStatsService,感觉用于记录进程运行时的统计信息,例如内存使用情况,写入/proc/stat文件
     51     mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
     52 
     53     //启动Android的权限检查服务,并注册对应的回调接口
     54     mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
     55     mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
     56             new IAppOpsCallback.Stub() {
     57                 @Override public void opChanged(int op, int uid, String packageName) {
     58                     if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
     59                         if (mAppOpsService.checkOperation(op, uid, packageName)
     60                                 != AppOpsManager.MODE_ALLOWED) {
     61                             runInBackgroundDisabled(uid);
     62                         }
     63                     }
     64                 }
     65             });
     66 
     67     //用于定义ContentProvider访问指定Uri对应数据的权限,aosp中似乎没有这文件
     68     mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
     69 
     70     //创建多用户管理器
     71     mUserController = new UserController(this);
     72 
     73     //获取OpenGL版本
     74     GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
     75             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
     76     ............
     77     //资源配置信息置为默认值
     78     mConfiguration.setToDefaults();
     79     mConfiguration.setLocales(LocaleList.getDefault());
     80     mConfigurationSeq = mConfiguration.seq = 1;
     81 
     82     //感觉用于记录进程的CPU使用情况
     83     mProcessCpuTracker.init();
     84 
     85     //解析/data/system/packages-compat.xml文件,该文件用于存储那些需要考虑屏幕尺寸的APK的一些信息
     86     //当APK所运行的设备不满足要求时,AMS会根据xml设置的参数以采用屏幕兼容的方式运行该APK
     87     mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
     88 
     89     //用于根据规则过滤一些Intent
     90     mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
     91 
     92     //以下的类,似乎用于管理和监控AMS维护的Activity Task信息
     93     //ActivityStackSupervisor是AMS中用来管理Activity启动和调度的核心类
     94     mStackSupervisor = new ActivityStackSupervisor(this);
     95     mActivityStarter = new ActivityStarter(this, mStackSupervisor);
     96     mRecentTasks = new RecentTasks(this, mStackSupervisor);
     97 
     98     //创建线程用于统计进程的CPU使用情况
     99     mProcessCpuThread = new Thread("CpuTracker") {
    100         @Override
    101         public void run() {
    102             while (true) {
    103                 try {
    104                     try {
    105                         //计算更新信息的等待间隔
    106                         //同时利用wait等待计算出的间隔时间
    107                         ......
    108                     } catch(InterruptedException e) {
    109                     }
    110                     //更新CPU运行统计信息
    111                     updateCpuStatsNow();
    112                 } catch (Exception e) {
    113                     ..........
    114                 }
    115             }
    116         }
    117     };
    118 
    119     //加入Watchdog的监控
    120     Watchdog.getInstance().addMonitor(this);
    121     Watchdog.getInstance().addThread(mHandler);
    122 }
    View Code

    从代码来看,AMS的构造函数还是相对比较简单的,主要工作就是初始化一些变量。
    大多数变量的用途,从命名上基本可以推测出来,实际的使用情况必须结合具体的场景才能进一步了解。

    AMS的start函数

     1 private void start() {
     2     //完成统计前的复位工作
     3     Process.removeAllProcessGroups();
     4 
     5     //开始监控进程的CPU使用情况
     6     mProcessCpuThread.start();
     7 
     8     //注册服务
     9     mBatteryStatsService.publish(mContext);
    10     mAppOpsService.publish(mContext);
    11     Slog.d("AppOps", "AppOpsService published");
    12     LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    13 }

    AMS的start函数比较简单,主要是:
    1、启动CPU监控线程。该线程将会开始统计不同进程使用CPU的情况。
    2、发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的继承ActivityManagerInternal的服务。

    至此AMS初始化相关的内容基本结束,从这些代码可以看出AMS涉及的类比较多,我们目前无法一一详述每个类的具体用途。
    有机会遇到具体的场景时,再深入分析,此处有个大致印象即可。

    2.3 将SystemServer纳入AMS的管理体系

    2.3.1 setSystemProcess

    AMS完成启动后,在SystemServer的startBootstrapServices函数中,
    下一个与AMS相关的重要调用就是AMS.setSystemProcess了:

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

    我们跟进一下setSystemProcess函数:

     1 public void setSystemProcess() {
     2     try {
     3         //以下是向ServiceManager注册几个服务
     4 
     5         //AMS自己
     6         ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
     7 
     8         //注册进程统计信息的服务
     9         ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
    10 
    11         //用于打印内存信息用的
    12         ServiceManager.addService("meminfo", new MemBinder(this));
    13 
    14         //用于输出进程使用硬件渲染方面的信息
    15         ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
    16 
    17         //用于输出数据库相关的信息
    18         ServiceManager.addService("dbinfo", new DbBinder(this));
    19 
    20         //MONITOR_CPU_USAGE默认为true
    21         if (MONITOR_CPU_USAGE) {
    22             //用于输出进程的CPU使用情况
    23             ServiceManager.addService("cpuinfo", new CpuBinder(this));
    24         }
    25 
    26         //注册权限管理服务
    27         ServiceManager.addService("permission", new PermissionController(this));
    28 
    29         //注册获取进程信息的服务
    30         ServiceManager.addService("processinfo", new ProcessInfoService(this));
    31 
    32         //1、向PKMS查询package名为“android”的应用的ApplicationInfo
    33         ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
    34                 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
    35 
    36         //2、调用installSystemApplicationInfo
    37         mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
    38 
    39         //3、以下与AMS的进程管理有关
    40         synchronized (this) {
    41             ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
    42             app.persistent = true;
    43             app.pid = MY_PID;
    44             app.maxAdj = ProcessList.SYSTEM_ADJ;
    45             app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
    46             synchronized (mPidsSelfLocked) {
    47                 mPidsSelfLocked.put(app.pid, app);
    48             }
    49             updateLruProcessLocked(app, false, null);
    50             updateOomAdjLocked();
    51         }
    52     } catch (PackageManager.NameNotFoundException e) {
    53         throw new RuntimeException(
    54                 "Unable to find android system package", e);
    55     }
    56 }

     从上面的代码可以看出,AMS的setSystemProcess主要有四个主要的功能:

    • 1、注册一些服务;
    • 2、获取package名为“android”的应用的ApplicationInfo;
    • 3、调用ActivityThread的installSystemApplicationInfo;
    • 4、AMS进程管理相关的操作。

     这四个主要的功能中,第一个比较简单,就是用Binder通信完成注册。
    我们主要看看后三个功能对应的流程。

    功能二,获取ApplicationInfo


    如前所述,这部分相关的代码为:

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

    我们先看看mContext.getPackageManager()的操作过程。

     我们已经知道mContext的实现类是ContextImpl,其中对应的代码如下:

     1 @Override
     2 public PackageManager getPackageManager() {
     3     if (mPackageManager != null) {
     4         return mPackageManager;
     5     }
     6 
     7     //依赖于ActivityThread的getPackageManager函数
     8     IPackageManager pm = ActivityThread.getPackageManager();
     9     if (pm != null) {
    10         // Doesn't matter if we make more than one instance.
    11         //利用PKMS的代理对象,构建ApplicationPackageManager
    12         //该类继承PackageManager
    13         return (mPackageManager = new ApplicationPackageManager(this, pm));
    14     }
    15 
    16     return null;
    17 }

    跟进一下ActivityThread中的getPackageManager:

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

    从上面的代码我们可以看到,AMS获取PKMS用到了Binder通信。

    实际上,PKMS由SystemServer创建,与AMS运行在同一个进程,AMS完全可以不经过Context、ActivityThread、Binder来获取PKMS。

    根据一些资料,推断出原生代码这么做的原因是:
    SystemServer进程中的服务,也使用Android运行环境来交互, 保留了组件之间交互接口的统一,为未来的系统保留了可扩展性。

    得到PKMS的代理对象后,AMS调用PKMS的getApplicationInfo接口,获取package名为”android”的ApplicationInfo。

    在AMS的setSystemProcess被调用前,PKMS已经启动了。
    之前分析PKMS的博客中,我们已经提到,在PKMS的构造函数中,它将解析手机中所有的AndroidManifest.xml,然后形成各种数据结构以维护应用的信息。

    getApplicationInfo就是通过package名,从对应的数据结构中,取出对应的应用信息,这部分内容主要就是查询数据结构的内容,不作深入分析。

    功能三,installSystemApplicationInfo
    得到framework-res.apk对应的ApplicationInfo后,需要将这部分ApplicationInfo保存到SystemServer对应的ActivityThread中。

    这部分对应的代码为:

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

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

    因此我们跟进一下ActivityThread的installSystemApplicationInfo函数:

     1 public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
     2     synchronized (this) {
     3         //调用SystemServer中创建出的ContextImpl的installSystemApplicationInfo函数
     4         getSystemContext().installSystemApplicationInfo(info, classLoader);
     5 
     6         // give ourselves a default profiler
     7         //创建一个Profiler对象,用于性能统计
     8         mProfiler = new Profiler();
     9     }
    10 }

    继续跟进ContextImpl的installSystemApplicationInfo函数:

    1 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
    2     //前面已经提到过mPackageInfo的类型为LoadedApk
    3     mPackageInfo.installSystemApplicationInfo(info, classLoader);
    4 }

     随着流程进入到LoadedApk:

     1 /**
     2 * Sets application info about the system package.
     3 */
     4 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
     5     //这个接口仅供系统进程调用,故这里断言一下
     6     assert info.packageName.equals("android");
     7 
     8     mApplicationInfo = info;
     9     mClassLoader = classLoader;
    10 }

    至此,我们知道了installSystemApplicationInfo的真相就是:
    将“android”对应的ApplicationInfo(即framework-res.apk对应的ApplicationInfo),
    加入到SystemServer之前调用createSystemContext时,创建出的LoadedApk中。
    毕竟SystemServer创建System Context时,PKMS并没有完成对手机中文件的解析,初始的LoadedApk中并没有持有有效的ApplicationInfo。

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

    由于framework-res.apk运行在SystemServer进程中,而AMS是专门用于进程管理和调度的,因此SystemServer进程也应该在AMS中有对应的管理结构。

    于是,AMS的下一步工作就是将SystemServer的运行环境和一个进程管理结构对应起来,并进行统一的管理。

    功能四, AMS进程管理

    注意到上面的ContentProvider注册到AMS后,进行了notifyAll的操作。
    举例来说:进程A需要查询一个数据库,需要通过进程B中的某个ContentProvider来实施。
    如果B还未启动,那么AMS就需要先启动B。在这段时间内,A需要等待B启动并注册对应的ContentProvider。
    B一旦完成ContentProvider的注册,就需要告知A退出等待以继续后续的查询工作。


    setSystemProcess函数中,进程管理相关的代码为:

     1 .............
     2 synchronized (this) {
     3     //创建进程管理对应的结构ProcessRecord
     4     ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
     5 
     6     //由于此时创建的是SystemServer进程对应ProcessRecord
     7     //因此设定了一些特殊值
     8     app.persistent = true;
     9     app.pid = MY_PID;
    10     app.maxAdj = ProcessList.SYSTEM_ADJ;
    11 
    12     //将SystemServer对应的ApplicationThread保存到ProcessRecord中
    13     app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
    14 
    15     synchronized (mPidsSelfLocked) {
    16         //按pid将ProcessRecord保存到mPidsSelfLocked中
    17         mPidsSelfLocked.put(app.pid, app);
    18     }
    19 
    20     //updateLruProcessLocked来调整进程在mLruProcess列表的位置
    21     //在这个列表中,最近活动过得进程总是位于前列,同时拥有Activity的进程位置总是前于只有Service的进程
    22     updateLruProcessLocked(app, false, null);
    23 
    24     //更新进程对应的oom_adj值(oom_adj将决定进程是否被kill掉)
    25     updateOomAdjLocked();
    26 }
    27 ...............

    这里我们仅分析一下创建进程管理结构的函数newProcessRecordLocked。
    updateLruProcessLocked和updateOomAdjLocked函数比较复杂,等对AMS有更多的了解后,再做分析。

     1 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
     2         boolean isolated, int isolatedUid) {
     3     //进程的名称
     4     String proc = customProcess != null ? customProcess : info.processName;
     5 
     6     //将用于创建该进程的电源统计项
     7     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
     8 
     9     final int userId = UserHandle.getUserId(info.uid);
    10     //isolated此时为false
    11     if (isolated) {
    12         ..........
    13     }
    14     //创建出对应的存储结构
    15     final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
    16 
    17     //判断进程是否常驻
    18     if (!mBooted && !mBooting
    19             && userId == UserHandle.USER_SYSTEM
    20             && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
    21         r.persistent = true;
    22     }
    23 
    24     //按进程名将ProcessRecord存入到AMS的变量mProcessNames中
    25     //该变量的类型为ProcessMap<ProcessRecord> 
    26     //结合前面的代码,我们知道AMS有两种方式可以取到ProcessRecord
    27     //一是根据进程名,二是根据进程名称
    28     addProcessNameLocked(r);
    29     return r;
    30 }

    跟进一下ProcessRecord的构造函数:

     1 ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
     2         String _processName, int _uid) {
     3     mBatteryStats = _batteryStats; //用于电量统计
     4     info = _info;  //保存ApplicationInfo
     5     ...........
     6     processName = _processName;  //保存进程名
     7 
     8     //一个进程能运行多个Package,pkgList用于保存package名
     9     pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));
    10 
    11     //以下变量和进程调度优先级有关
    12     maxAdj = ProcessList.UNKNOWN_ADJ;
    13     curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
    14     curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
    15 
    16     //决定进程是否常驻内存(即使被杀掉,系统也会重启它)
    17     persistent = false;
    18 
    19     removed = false;
    20     lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
    21 }

    总结
    至此,我们对AMS的setSystemProcess函数分析告一段落。
    从上面的代码可以看出,在这个函数中除了发布一些服务外,主要是:
    将framework-res.apk的信息加入到SystemServer对应的LoadedApk中,同时构建SystemServer进程对应的ProcessRecord,
    以将SystemServer进程纳入到AMS的管理中。

    2.3.2  AMS的installSystemProviders


    接下来AMS启动相关的操作,定义于SystemServer的startOtherServices函数中。

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

    我们跟进一下AMS的installSystemProviders函数:

     1 public final void installSystemProviders() {
     2     List<ProviderInfo> providers;
     3     synchronized (this) {
     4         //AMS根据进程名取出SystemServer对应的ProcessRecord
     5         ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
     6 
     7         //1、得到该ProcessRecord对应的ProviderInfo
     8         providers = generateApplicationProvidersLocked(app);
     9 
    10         //这里仅处理系统级的Provider
    11         if (providers != null) {
    12             for (int i=providers.size()-1; i>=0; i--) {
    13                 ProviderInfo pi = (ProviderInfo)providers.get(i);
    14                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
    15                         Slog.w(TAG, "Not installing system proc provider " + pi.name
    16                                 + ": not system .apk");
    17                         providers.remove(i);
    18                     }
    19                 }
    20             }
    21         }
    22     }
    23 
    24     if (providers != null) {
    25         //2、安装Provider
    26         mSystemThread.installSystemProviders(providers);
    27     }
    28 
    29     //创建ContentObserver监控Settings数据库中Secure、System和Global表的变化
    30     mCoreSettingsObserver = new CoreSettingsObserver(this);
    31 
    32     //创建ContentObserver监控Settings数据库中字体大小的变化
    33     mFontScaleSettingObserver = new FontScaleSettingObserver();
    34 }

    从上面的代码可以看出,installSystemProviders主要是加载运行在SystemServer进程中的 ContentProvider,即SettingsProvider.apk (定义于frameworks/base/packages/SettingsProvider)。

    上面有两个比较重要的函数:
    1、generateApplicationProvidersLocked返回一个进程对应的ProviderInfo List。
    2、ActivityThread可以看做是进程的Android运行环境,因此它的installSystemProviders表示为对应进程安装ContentProvider。

    当SettingsProvider被加载到SystemServer进程中运行后,AMS就注册了两个ContentObserver监控SettingsProvider中的字段变化。
    AMS监控的字段影响范围比较广,例如字体发生变化时,很多应用的显示界面都需要做出调整。
    这也许就是让AMS来负责监控这些字段的原因。

     2.4 AMS的systemReady

    接下来,我们看看AMS启动的最后一部分:systemReady。
    该函数在SystemServer中startOtherServices的最后被调用:

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

    我们分段看看AMS中systemReady的处理流程。
    此处的分段并没有实际的意义,只是代码确实太长了,并且连续性不够,因此分开描述。

    阶段一

     1 public void systemReady(final Runnable goingCallback) {
     2     synchronized(this) {
     3         ..........
     4         //这一部分主要是调用一些关键服务SystemReady相关的函数,
     5         //进行一些等待AMS初始完,才能进行的工作
     6 
     7         // Make sure we have the current profile info, since it is needed for security checks.
     8         mUserController.onSystemReady();
     9 
    10         mRecentTasks.onSystemReadyLocked();
    11         mAppOpsService.systemReady();
    12         mSystemReady = true;
    13     }
    14 
    15     ArrayList<ProcessRecord> procsToKill = null;
    16     synchronized(mPidsSelfLocked) {
    17         //mPidsSelfLocked中保存当前正在运行的所有进程的信息
    18         for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
    19             ProcessRecord proc = mPidsSelfLocked.valueAt(i);
    20 
    21             //在AMS启动完成前,如果没有FLAG_PERSISTENT标志的进程已经启动了,
    22             //就将这个进程加入到procsToKill中
    23             if (!isAllowedWhileBooting(proc.info)){
    24                 if (procsToKill == null) {
    25                     procsToKill = new ArrayList<ProcessRecord>();
    26                 }
    27                 procsToKill.add(proc);
    28             }
    29         }
    30     }
    31 
    32     synchronized(this) {
    33         //利用removeProcessLocked关闭procsToKill中的进程
    34         if (procsToKill != null) {
    35             for (int i=procsToKill.size()-1; i>=0; i--) {
    36                 ProcessRecord proc = procsToKill.get(i);
    37                 Slog.i(TAG, "Removing system update proc: " + proc);
    38                 removeProcessLocked(proc, true, false, "system update done");
    39             }
    40         }
    41 
    42         // Now that we have cleaned up any update processes, we
    43         // are ready to start launching real processes and know that
    44         // we won't trample on them any more.
    45 
    46         //至此系统准备完毕
    47         mProcessesReady = true;
    48     }
    49     ............
    50     //根据数据库和资源文件,获取一些配置参数
    51     retrieveSettings();
    52 
    53     final int currentUserId;
    54     synchronized (this) {
    55         //得到当前的用户ID
    56         currentUserId = mUserController.getCurrentUserIdLocked();
    57 
    58         //读取urigrants.xml,为其中定义的ContentProvider配置对指定Uri数据的访问/修改权限
    59         //原生代码中,似乎没有urigrants.xml文件
    60         //实际使用的grant-uri-permission是分布式定义的
    61         readGrantedUriPermissionsLocked();
    62     }
    63     ..........
    View Code

    这一部分的工作主要是调用一些关键服务的初始化函数,
    然后杀死那些没有FLAG_PERSISTENT却在AMS启动完成前已经存在的进程,
    同时获取一些配置参数。
    需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。

    阶段二

     1 //1、调用参数传入的runnable对象,SystemServer中有具体的定义
     2 if (goingCallback != null) goingCallback.run();
     3 ..............
     4 //调用所有系统服务的onStartUser接口
     5 mSystemServiceManager.startUser(currentUserId);
     6 .............
     7 synchronized (this) {
     8     // Only start up encryption-aware persistent apps; once user is
     9     // unlocked we'll come back around and start unaware apps
    10     2、启动persistent为1的application所在的进程
    11     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
    12 
    13     // Start up initial activity.
    14     mBooting = true;
    15 
    16     // Enable home activity for system user, so that the system can always boot
    17     //当isSplitSystemUser返回true时,意味者system user和primary user是分离的
    18     //这里应该是让system user也有启动home activity的权限吧
    19     if (UserManager.isSplitSystemUser()) {
    20         ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
    21         try {
    22             AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
    23                     PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
    24                     UserHandle.USER_SYSTEM);
    25         } catch (RemoteException e) {
    26             throw e.rethrowAsRuntimeException();
    27         }
    28     }
    29 
    30     //3、启动Home
    31     startHomeActivityLocked(currentUserId, "systemReady");
    32 
    33     try {
    34         //发送消息,触发处理Uid错误的Application
    35         if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
    36             ..........
    37             mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
    38         }
    39     } catch (RemoteException e) {
    40     }
    41     //发送一些广播信息
    42     ............
    43     //这里暂时先不深入,等进一步了解Activity的启动过程后,再做了解
    44     mStackSupervisor.resumeFocusedStackTopActivityLocked();
    45     ............
    46 }
    47 .............
    View Code

    从部分代码来看,主要的工作就是通知一些服务可以进行systemReady相关的工作,并进行启动服务或应用进程的工作。

    2.4.1 调用回调接口
    回调接口的具体内容定义与SystemServer.java中,其中会调用大量服务的onBootPhase函数、一些对象的systemReady函数或systemRunning函数。
    此处,我们仅截取一些比较特别的内容:

     1 public void run() {
     2     ............
     3     try {
     4         //启动NativeCrashListener监听"/data/system/ndebugsocket"中的信息
     5         //实际上是监听debuggerd传入的信息
     6         mActivityManagerService.startObservingNativeCrashes();
     7     } catch (Throwable e) {
     8         reportWtf("observing native crashes", e);
     9     }
    10     ............
    11     try {
    12         //启动SystemUi
    13         startSystemUi(context);
    14     } catch (Throwable e) {
    15         reportWtf("starting System UI", e);
    16     }
    17     ............
    18     //这个以前分析过,启动Watchdog
    19     Watchdog.getInstance().start();
    20     ....................
    21 }

     回调接口中的内容较多,不做一一分析。

    2.4.2 启动persistent标志的进程
    我们看看startPersistentApps对应的内容:

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

    跟进一下addAppLocked函数:

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

    这里最终将通过startProcessLocked函数,启动实际的应用进程。
    正如之前分析zygote进程时,提过的一样,zygote中的server socket将接收消息,然后为应用fork出进程。

    2.4.3 启动Home Activity
    看看启动Home Activity对应的startHomeActivityLocked函数:

     1 boolean startHomeActivityLocked(int userId, String reason) {
     2     ..............
     3     Intent intent = getHomeIntent();
     4     //根据intent中携带的ComponentName,利用PKMS得到ActivityInfo
     5     ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
     6     if (aInfo != null) {
     7         intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
     8         aInfo = new ActivityInfo(aInfo);
     9         aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
    10 
    11         //此时home对应进程应该还没启动,app为null
    12         ProcessRecord app = getProcessRecordLocked(aInfo.processName,
    13                 aInfo.applicationInfo.uid, true);
    14         if (app == null || app.instrumentationClass == null) {
    15             intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
    16             //启动home
    17             mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
    18         }
    19     } else {
    20         ..........
    21     }
    22     return true;
    23 }

    这里暂时先不深究Home Activity启动的具体过程。


    从手头的资料来看,当Home Activity启动后,
    ActivityStackSupervisor中的activityIdleInternalLocked函数将被调用(具体调用过程,还需要研究):

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

    在checkFinishBootingLocked函数中:

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

    最终,AMS的finishBooting函数将被调用:

     1 final void finishBooting() {
     2     .........
     3     //以下是注册广播接收器,用于处理需要重启的package
     4     IntentFilter pkgFilter = new IntentFilter();
     5     pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
     6     pkgFilter.addDataScheme("package");
     7     mContext.registerReceiver(new BroadcastReceiver() {
     8         @Override
     9         public void onReceive(Context context, Intent intent) {
    10             String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
    11             if (pkgs != null) {
    12                 for (String pkg : pkgs) {
    13                     synchronized (ActivityManagerService.this) {
    14                         if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
    15                                 0, "query restart")) {
    16                             setResultCode(Activity.RESULT_OK);
    17                             return;
    18                         }
    19                     }
    20                 }
    21             }
    22        }
    23     }, pkgFilter);
    24     ...........
    25     // Let system services know.
    26     mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
    27 
    28     //以下是启动那些等待启动的进程
    29     synchronized (this) {
    30         // Ensure that any processes we had put on hold are now started
    31         // up.
    32         final int NP = mProcessesOnHold.size();
    33             if (NP > 0) {
    34                 ArrayList<ProcessRecord> procs =
    35                         new ArrayList<ProcessRecord>(mProcessesOnHold);
    36                 for (int ip=0; ip<NP; ip++) {
    37                     .................
    38                     startProcessLocked(procs.get(ip), "on-hold", null);
    39                 }
    40             }
    41         }
    42     }
    43     ..............
    44     if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
    45         // Start looking for apps that are abusing wake locks.
    46         //每15min检查一次系统各应用进程使用电量的情况,如果某个进程使用WakeLock的时间过长
    47         //AMS将关闭该进程
    48         Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
    49         mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
    50 
    51         // Tell anyone interested that we are done booting!
    52         SystemProperties.set("sys.boot_completed", "1");
    53         .................
    54         //此处从代码来看发送的是ACTION_LOCKED_BOOT_COMPLETED广播
    55         //在进行unlock相关的工作后,mUserController将调用finishUserUnlocking,发送SYSTEM_USER_UNLOCK_MSG消息给AMS
    56         //AMS收到消息后,调用mUserController的finishUserUnlocked函数,经过相应的处理后,
    57         //在mUserController的finishUserUnlockedCompleted中,最终将会发送ACTION_BOOT_COMPLETED广播
    58         mUserController.sendBootCompletedLocked(.........);
    59         .................
    60     }
    61 }
    View Code

    最终,当AMS启动Home Activity结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落。



    总结图


  • 相关阅读:
    Laya中使用Protobuf
    Laya中第三方库的使用
    Laya的骨骼换装
    Laya的粒子效果
    Laya的预设Prefab (预制件)
    Egret EUI Tab + ViewStack
    Egret 划线手势动画 (切水果)
    Egret3.2.6老项目转成5.2.22微信小游戏,遇到exml加载不了问题
    AndroidUI设计 之 图片浏览器
    Android应用的自动更新模块
  • 原文地址:https://www.cnblogs.com/neo-java/p/7146424.html
Copyright © 2011-2022 走看看