Android(java)学习笔记104:Framework运行环境之启动SystemServer进程
1. SystemServer进程
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()函数开始运行。
2. 启动各种系统服务线程
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));
- }
3. 启动第一个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的启动过程。
Android(java)学习笔记104:Framework运行环境之启动SystemServer进程的更多相关文章
- Android(java)学习笔记161:Framework运行环境之启动SystemServer进程
SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的.与启动普通进程的差别 ...
- Java学习笔记【一、环境搭建】
今天把java的学习重新拾起来,一方面是因为公司的项目需要用到大数据方面的东西,需要用java做语言 另一方面是原先使用的C#公司也在慢慢替换为java,为了以后路宽一些吧,技多不压身 此次的学习目标 ...
- Java 学习笔记之 Thread运行过程分析
Thread运行过程分析: 以下是一个最普通的Thread实现过程,我们今天就来看仔细分析下他是如何运行的. public class ThreadRunMain { public static vo ...
- JAVA学习笔记16——线程的创建和启动
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码).Java使用线程执行体来代表这段 ...
- java学习笔记(1)java的基础介绍 、JDK下载、配置环境变量、运行java程序
java工程师是开发软件的 什么是软件呢? 计算机包括两部分: 硬件: 鼠标.键盘.显示器.主机箱内部的cpu.内存条.硬盘等 软件: 软件包括:系统软件和应用软件 系统软件:直接和硬件交互的软件:w ...
- Android Studio 学习笔记(一)环境搭建、文件目录等相关说明
Android Studio 学习笔记(一)环境搭建.文件目录等相关说明 引入 对APP开发而言,Android和iOS是两大主流开发平台,其中区别在于 Android用java语言,用Android ...
- Kettle学习笔记(一)— 环境部署及运行
目录 Kettle学习笔记(一)-环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 Kettle简介 Ket ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
随机推荐
- rowid去重(转)
实际应用场景:数据去重--当多条记录主键相同或者多条记录完全一致时,只需要留下一条记录 delete from bal_acctbook_info where rowid not in (select ...
- 洛谷P1373 小a和uim之大逃离
P1373 小a和uim之大逃离 题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从 ...
- 禁止tableview 像上滑动
tableView有一个bounces属性.默认YES,所以tableView上下用力拉都会有弹性滑动,如下设置可以禁止,但是这样的话上下弹性都没了 而经常的需求是上方不要弹性,下方要弹性,可以用监听 ...
- nagios部署配置流程
nagios部署配置流程 nagios服务端:1.部署nagios服务端(参考nagios官方部署文档).nagios-plugin.php.apache2 2.需要在服务端添/etc/hosts中添 ...
- ffmpeg文件生成m3u8文件及ts切片程序(一)
ffmpeg文件生成m3u8文件及ts切片程序(一) 实现目标:输入本地文件,实现m3u8切片,功能点请看注释,注意:注释很重要. 参考: http://www.cnblogs.com/mystory ...
- pat1078. Hashing (25)
1078. Hashing (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The task of t ...
- 下载安装MariaDB Galera 10.1
因为无法访问外网, 配置官网的yum无法下载MariaDB Galera(在MariaDB 10.1 及之后内置了Galera, 不像之前那样需要独立安装) 需要在下载的包 MariaDB-10.1. ...
- MongoDB Linux 安装配置 后台运行
介绍安装的文档很多,可以参考这篇: http://www.mkyong.com/mongodb/how-to-install-mongodb-on-mac-os-x/ 安装完后你可能会碰到的2个问题. ...
- Java排序算法(二)
java排序算法(二) 二.改进排序算法 2.1希尔排序 定义:希尔排序(ShellSort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. ...
- client的使用
document.documentElement.clientHeight = 464 // 指窗口的可见高度的大小 document.body.clientHeight = 1577 // 指窗口的 ...