一. AMS简介

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

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

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

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

   AMS分析 -- 启动过程

                                                         图1 AmS基本类图

 

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

 

 

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

  AMS分析 -- 启动过程

                                                           图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和应用进程之间的交互函数。

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类用于保存应用的全局状态。

AMS分析 -- 启动过程

我们经常使用的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函数。

AMS分析 -- 启动过程

上图表示了进程的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

相关文章: