SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的。与启动普通进程的差别在于:类zygote为启动SystemServer提供专门的函数startSystemServer(),而不是标准的forAndSpecilize函数。同时,SystemServer进程启动后首先要做的事情和普通进程也有所差别。
函数startSystemServer()的关键功能如下:
(1)定义一个String[]数组,数组中包含了要启动进程的相关信息,其中最后一项指定新进程启动后装载的第一个Java类,此处就是为类com.android.SystemServer
(2)调用forkSystemServer()从当前的zygote进程孵化新的进程。该函数是一个native函数,其作用与folkAndSpecilize()相似
(3)启动新进程后,在函数handleSystemServerProcess()中主要完成如下两件事件。
1.关闭Socket服务器
2.执行com.android.server.SystemServer类中函数main()。
除了这两个主要事情外,还做了一些额外的运行环境配置,这些配置主要在函数commonInit()和函数zygoteInitNative()中完成。一旦配置好SystemServer的进程环境后,就从类SystemServer中main()函数开始运行。
1.启动各种系统服务线程
SystemServer进程在Android的运行环境中扮演了"中枢"的作用,在APK应用中能够直接交互的大部分系统服务都在这个进程中运行,例如WindowManagerServer(Wms)、ActivityManagerSystemServive(AMS)、PackageManagerServer(PMS)等常见的应用,这些系统服务都是以一个线程的方式存在与SystemServer进程之中。下面就来介绍都有哪些服务进程,及其启动的顺序。
SystemServer中的main()函数首先调用的是函数init1(),这是一个native函数,内部会进行一些与Dalvik虚拟机相关的初始化工作。该函数执行完毕后,其内部会调用Java端的init2()函数,这就是为什么Java源码中没有引用init2()的地方,主要的系统服务都是在init2()函数中完成。
该函数首先创建了一个ServerThread对象,该对象是一个线程,然后直接运行该线程,从ServerThread的run()方法内部开始真正启动各种服务线程。基本上每个服务都对应的Java类,从编码规范的角度来看,启动这些服务模式可归类为如下三种:
(1)模式1:是指直接使用构造函数构造一个服务,由于大多数服务都对应一个线程,因此,在构造函数内部就创建一个线程并自动运行。
(2)模式2:是指服务类会提供一个getInstance()方法,通过该方法获取该服务对象,这样的好处是保证系统中仅包含一个该服务对象。
(3)模式3:是指服务类的main()函数中开始执行。
SystemServer中启动服务列表:
服务类名称 |
作用描述 |
启动模式 |
EntropyService |
提供伪随机数 |
1.0 |
PowerManagerService |
电源管理服务 |
1.2/3 |
ActivityManagerService |
最核心的服务之一,管理 Activity |
自定义 |
TelephonyRegistry |
通过该服务注册电话模块的事件响应,比如重启、关闭、启动等 |
1.0 |
PackageManagerService |
程序包管理服务 |
3.3 |
AccountManagerService |
账户管理服务,是指联系人账户,而不是 Linux 系统的账户 |
1.0 |
ContentService |
ContentProvider 服务,提供跨进程数据交换 |
3.0 |
BatteryService |
电池管理服务 |
1.0 |
LightsService |
自然光强度感应传感器服务 |
1.0 |
VibratorService |
震动器服务 |
1.0 |
AlarmManagerService |
定时器管理服务,提供定时提醒服务 |
1.0 |
WindowManagerService |
Framework 最核心的服务之一,负责窗口管理 |
3.3 |
BluetoothService |
蓝牙服务 |
1.0 + |
DevicePolicyManagerService |
提供一些系统级别的设置及属性 |
1.3 |
StatusBarManagerService |
状态栏管理服务 |
1.3 |
ClipboardService |
系统剪切板服务 |
1.0 |
InputMethodManagerService |
输入法管理服务 |
1.0 |
NetStatService |
网络状态服务 |
1.0 |
NetworkManagementService |
网络管理服务 |
NMS.create() |
ConnectivityService |
网络连接管理服务 |
2.3 |
ThrottleService |
暂不清楚其作用 |
1.3 |
(续表)
服务类名称 |
作用描述 |
启动模式 |
AccessibilityManagerService |
辅助管理程序截获所有的用户输入,并根据这 些输入给用户一些额外的反馈,起到辅助的效果 |
1.0 |
MountService |
挂载服务,可通过该服务调用 Linux 层面的 mount 程序 |
1.0 |
NotificationManagerService |
通知栏管理服务, Android 中的通知栏和状 态栏在一起,只是界面上前者在左边,后者在右边 |
1.3 |
DeviceStorageMonitorService |
磁盘空间状态检测服务 |
1.0 |
LocationManagerService |
地理位置服务 |
1.3 |
SearchManagerService |
搜索管理服务 |
1.0 |
DropBoxManagerService |
通过该服务访问 Linux 层面的 Dropbox 程序 |
1.0 |
WallpaperManagerService |
墙纸管理服务,墙纸不等同于桌面背景, 在 View 系统内部,墙纸可以作为任何窗口的背景 |
1.3 |
AudioService |
音频管理服务 |
1.0 |
BackupManagerService |
系统备份服务 |
1.0 |
AppWidgetService |
Widget 服务 |
1.3 |
RecognitionManagerService |
身份识别服务 |
1.3 |
DiskStatsService |
磁盘统计服务 |
1.0 |
AmS的启动模式如下:
调用main()函数,返回一个Context对象,而不是AmS服务本身。
调用AmS.setSystemProcess()。
调用AmS.installProviders()。
调用systemReady(),当AmS执行完systemReady()后,会相继启动相关联服务的systemReady()函数,完成整体初始化。
备注:
ystemServer是Android系统的一个核心进程,它是由zygote进程创建的,因此在android的启动过程中位于zygote之后。android的所有服务循环都是建立在 SystemServer之上的。在SystemServer中,将可以看到它建立了android中的大部分服务,并通过ServerManager的add_service方法把这些服务加入到了ServiceManager的svclist中。从而完成ServcieManager对服务的管理。
先看下SystemServer的main函数:
- native public static void init1(String[]args);
- public static void main(String[] args) {
- if(SamplingProfilerIntegration.isEnabled()) {
- SamplingProfilerIntegration.start();
- timer = new Timer();
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- SamplingProfilerIntegration.writeSnapshot("system_server");
- }
- }, SNAPSHOT_INTERVAL,SNAPSHOT_INTERVAL);
- }
- // The system server has to run all ofthe time, so it needs to be
- // as efficient as possible with itsmemory usage.
- VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
- System.loadLibrary("android_servers"); //加载本地库android_servers
- init1(args);
- }
在main函数中主要是调用了本地方法init1(args), 他的实现位于../base/services/jni/com_android_server_SystemService.cpp中
- static voidandroid_server_SystemServer_init1(JNIEnv* env, jobject clazz)
- {
- system_init();
- }
进一步来看system_init,在这里面看到了闭合循环管理框架:
- runtime->callStatic("com/android/server/SystemServer","init2");//回调了SystemServer.java中的init2方法
- if (proc->supportsProcesses()) {
- LOGI("System server: enteringthread pool.\n");
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- LOGI("System server: exitingthread pool.\n");
- }
通过调用com/android/server/SystemServer.java中的init2方法完成service的注册。在init2方法中主要建立了以ServerThread线程,然后启动线程来完成service的注册。
- public static final void init2() {
- Slog.i(TAG, "Entered the Androidsystem server!");
- Thread thr = new ServerThread();
- thr.setName("android.server.ServerThread");
- thr.start();
- }
具体实现service的注册在ServerThread的run方法中:
- try {
- Slog.i(TAG, "EntropyService");
- ServiceManager.addService("entropy", new EntropyService());
- Slog.i(TAG, "PowerManager");
- power = new PowerManagerService();
- ServiceManager.addService(Context.POWER_SERVICE, power);
- Slog.i(TAG, "ActivityManager");
- context =ActivityManagerService.main(factoryTest);
- Slog.i(TAG, "TelephonyRegistry");
- ServiceManager.addService("telephony.registry", newTelephonyRegistry(context));
- }
2.启动第一个Activity:
当启动以上服务线程后,ActivityManagerService(AMS)服务是以systemReady()调用完成最后启动的,而在AmS的函数systemReady()内部的最后一段代码则发出启动任务队列中最上面一个Activity的消息。因为在系统刚启动时,mMainStack队列中并没有任何Activity对象,所以在类AcitivityStack中将调用startHomeActivityLocked()。
开机后,系统从哪个Activity开始执行这一动作,完全取决于mMainStack队列中的第一个Activity对象。如果在ActivityManagerServer启动时能够构造一个Activity对象(并不是说构造出一个Activity类的对象),并将其放到mMainStack队列中,那么第一个运行的Activity对象就是这个Activity,这一点不像其他操作系统中通过设置一个固定程序作为第一个启动程序。
在Ams的startHomeAcitivityLocked()中,系统发出一个catagory字段包含CATEGORY_HOME的intent。
无论是哪个应用程序,只要声明自己能够响应该intent,那么就可以被认为是Home程序,这是为什么在Android领域会存在各种"Home程序"的原因。系统并没有任何程序赋予"Home"特权,而只是把这个权利交给了用户。当在系统中有多个程序能够响应该intent时,系统会弹出一个对话框,请求用户选择启动哪个程序,并允许用户记住该选择,从而使得以后每次按Home都会启动相同Activity,这就是第一个Acitivity的启动过程。