本文基于安卓6.0源码,对systemserver进程的启动与管理的基本过程进行介绍。
从Zygote进程初始化ZygoteInit.main()中调用startSystemServer()fork出子进程开始。
SystemServer负责启动和管理整个java framework,包含ActivityManager,WindowManager,PackageManager以及PowerManager等。
在一号进程init(),解析init.rc文件,并启动其中的Zygote服务,会调用ZygoteInit.main()方法,在其中先fork出SystemServer进程,fork出进程之后根据pid分别处理子进程与父进程。在子进程中将复制过来的socket关闭(fork规则:读时共享,写时复制)。
init完成之后,抛出ZygoteInit.MethodAndArgsCaller(m, argv)异常后,抓取该异常执行到caller.run()然后反射调用SysemServer.main()方法启动SystemServer。
在SysemServer.main()中,会直接调用SystemServer.run()方法启动SystemServer。
Start! GO
1、SystemServer启动概览
SystemServer.run()方法中会调用到SystemServer启动的全部方法,最重要的几点步骤总结如下:
- 准备主线程Looper
- 加载android_servers.so库
- 初始化系统上下文
- 启动80多种系统服务
- 进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再进行处理。
SystemServer.java
private void run() {
//设置最早时间戳,不能早于1970年。安卓时间戳的计算是从1970年开始的。
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//设置语言相关
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
//正式开始SystemServer进程的启动,Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
...
//确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
//1:准备主线程Looper
Looper.prepareMainLooper();
//2:加载android_servers.so库
System.loadLibrary("android_servers");
//检测上次关机过程是否失败,该方法可能不会返回
performPendingShutdown();
//3:初始化系统上下文
createSystemContext();
// 创建系统服务管理(mSystemServiceManager),并将该管理加入到本地服务(LocalServices)
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//4:启动服务
//启动引导服务也可以说是关键服务,最重要的服务。包括AMS,PKMS,DisplayManagerService等。核心服务与其他服务会被这些服务所依赖,所以需要先启动这些引导服务。startBootstrapServices()
//启动核心服务,包括WindowManagerService,InputManagerService等。
//启动其他的服务,startOtherServices()
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
...
//5:进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再进行处理。
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
2、初始化系统上下文
SystemServer.createSystemContext()
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
//设置一下系统主题
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
2.1 ActivityThread activityThread = ActivityThread.systemMain()
ActivityThread.systemMain()
public static ActivityThread systemMain() {
//低内存上不开启硬件加速,因为会增加过多的开销。这里可以不必在意,关注系统上下文初始化过程即可。
if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(true);
} else {
HardwareRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
//这里thread.attach(true),ActivityThread的attach函数是任何进程创建过程中都会调用的。
//需要注意的是,app创建时调用的是attach(false),进入attach()函数之后,会根据是否是系统进程判断,执行逻辑会大不相同。
thread.attach(true);
return thread;
}
下面看一下attach函数,这里仅需要了解即可。我会在application的启动过程中详细介绍attach流程。
- 创建mInstrumentation
- 创建appContenx
- 创建application
ActivityThread.attach()
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//如果是用户进程,这里会直接调用AMS的代理的attachApplication(mAppThread)。把自身的mApplicationThread类型的成员变量(mAppThread),直接传递过去。
//这里还是关注系统进程的执行逻辑
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
//1:先创建一个mInstrumentation,它是ActivityThread的成员,每一个ActicityThread对象都有一个mInstrumentation。
//我的理解是,使用该类可以去控制和观察application及activity生命周期。
//这里知道一下即可,不必要太关注。
mInstrumentation = new Instrumentation();
//2:创建appContenx,ContextImpl类是Activity.java,ContextWrapper.java中方法的实现类。
//比如startActivity(),start/bindService(),sendBroadcast()等方法都是在该类中实现的。
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//3:然后是makeApplication,即创建application。
//每一个进程只有一个application,可以在makeApplication()中看到,如果application不为空,会直接返回,而不会新创建application。
//这里暂时还不是特别明白,以后再深究。
//在makeApplication()调用了 instrumentation.callApplicationOnCreate(app),这里调用了onCreate()实际上调用的application.onCreate(),以后再深究吧。
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
2.2 mSystemContext = activityThread.getSystemContext()
创建系统上下文,简单的单例模式。
ActivityThread.getSystemContext()
//简单的单例模式,创建系统上下文
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
3、启动服务
启动服务过程中,安卓将这些服务分为3类。
- 第一类:startBootstrapServices(),启动系统关键服务。这些服务是安卓系统中最关键的服务,其他服务可能依赖于这些服务的创建,是开机启动中最紧急需要启动的服务。
- 第二类 :startCoreServices(),启动核心服务。系统中的核心服务,缺少这些服务手机基本无法使用。
- 第三类:startOtherServices(),启动其余的服务。除非必要,我们自己开发的普通系统服务都应该放在这里启动。
在这些服务的最后,一定都会调用serviceManager.addService()方法,将这些服务注册到serviceManager中,等待调用。
网友评论