Android系统启动流程(三)解析SyetemServer进程启动过程

cl = createSystemServerClassLoader(systemServerClasspath,

parsedArgs.targetSdkVersion);

Thread.currentThread().setContextClassLoader(cl);

}

RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//2

}

}

SyetemServer进程是复制了Zygote进程的地址空间,因此也会得到Zygote进程创建的Socket,这个Socket对于SyetemServer进程没有用处,因此,需要注释1处的代码来关闭该Socket。在注释2处调用RuntimeInit的zygoteInit函数,它的代码如下所示。

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

throws ZygoteInit.MethodAndArgsCaller {

if (DEBUG) Slog.d(TAG, “RuntimeInit: Starting application from zygote”);

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “RuntimeInit”);

redirectLogStreams();

commonInit();

nativeZygoteInit();//1

applicationInit(targetSdkVersion, argv, classLoader);//2

}

注释1处调用nativeZygoteInit函数,一看函数的名称就知道调用Native层的代码。

启动Binder线程池

接着我们来查看nativeZygoteInit函数对用的JNI文件,如下所示。

frameworks/base/core/jni/AndroidRuntime.cpp

static const JNINativeMethod gMethods[] = {

{ “nativeFinishInit”, “()V”,

(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },

{ “nativeZygoteInit”, “()V”,

(void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },

{ “nativeSetExitWithoutCleanup”, “(Z)V”,

(void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },

};

通过JNI的gMethods数组,可以看出nativeZygoteInit函数对应的是JNI文件AndroidRuntime.cpp的com_android_internal_os_RuntimeInit_nativeZygoteInit函数:

static AndroidRuntime* gCurRuntime = NULL;

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)

{

gCurRuntime->onZygoteInit();

}

这里gCurRuntime是AndroidRuntime类型的指针,AndroidRuntime的子类AppRuntime在app_main.cpp中定义,我们来查看AppRuntime的onZygoteInit函数,代码如下所示。

frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()

{

sp proc = ProcessState::self();

ALOGV(“App process: starting thread pool.\n”);

proc->startThreadPool();//1

}

注释1处的代码用来启动一个Binder线程池,这样SyetemServer进程就可以使用Binder来与其他进程进行通信了。看到这里我们知道RuntimeInit.java的nativeZygoteInit函数主要做的就是启动Binder线程池。

invokeStaticMain

我们再回到RuntimeInit.java的代码,在注释2处调用了applicationInit函数,代码如下所示。

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

throws ZygoteInit.MethodAndArgsCaller {

invokeStaticMain(args.startClass, args.startArgs, classLoader);

}

applicationInit函数中主要调用了invokeStaticMain函数:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)

throws ZygoteInit.MethodAndArgsCaller {

Class<?> cl;

try {

cl = Class.forName(className, true, classLoader);//1

} catch (ClassNotFoundException ex) {

throw new RuntimeException(

"Missing class when invoking static main " + className,

ex);

}

Method m;

try {

m = cl.getMethod(“main”, new Class[] { String[].class });//2

} catch (NoSuchMethodException ex) {

throw new RuntimeException(

"Missing static main on " + className, ex);

} catch (SecurityException ex) {

throw new RuntimeException(

"Problem getting static main on " + className, ex);

}

int modifiers = m.getModifiers();

if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {

throw new RuntimeException(

"Main method is not public and static on " + className);

}

throw new ZygoteInit.MethodAndArgsCaller(m, argv);//3

}

注释1处className为“com.android.server.SystemServer”,因此通过反射返回的cl为SystemServer类。注释2处找到SystemServer中的main函数。在注释3处将找到的main函数传入到MethodAndArgsCaller异常中并抛出该异常。截获MethodAndArgsCaller异常的代码在ZygoteInit.java的main函数中,如下所示。

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {

closeServerSocket();

} catch (MethodAndArgsCaller caller) {

caller.run();//1

} catch (RuntimeException ex) {

Log.e(TAG, “Zygote died with exception”, ex);

closeServerSocket();

throw ex;

}

}

在注释1处调用了MethodAndArgsCaller的run函数:

public void run() {

try {

mMethod.invoke(null, new Object[] { mArgs });

} catch (IllegalAccessException ex) {

}

}

}

这里mMethod指的就是SystemServer的main函数,因此main函数被动态调用。

3.解析SyetemServer进程

我们先来查看SystemServer的main函数:

frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {

new SystemServer().run();

}

main函数中只调用了SystemServer的run函数,如下所示。

private void run() {

System.loadLibrary(“android_servers”);//1

mSystemServiceManager = new SystemServiceManager(mSystemContext);//2

LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

try {

Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, “StartServices”);

startBootstrapServices();//3

startCoreServices();//4

startOtherServices();//5

} catch (Throwable ex) {

Slog.e(“System”, “******************************************”);

Slog.e(“System”, “************ Failure starting system services”, ex);

throw ex;

} finally {

Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

}

}

run函数代码很多,关键就是在注释1处加载了libandroid_servers.so。接下来在注释2处创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。启动系统的各种服务,在注释3中的startBootstrapServices函数中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。在注释4处的函数中则启动了BatteryService、UsageStatsService和WebViewUpdateService。注释5处的startOtherServices函数中则启动了CameraService、AlarmManagerService、VrManagerService等服务,这些服务的父类为SystemService。从注释3、4、5的函数可以看出,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务为一些非紧要和一些不需要立即启动的服务。系统服务大约有80多个,这里列出部分系统服务以及它们的作用如下表所示:

| 引导服务 | 作用 |

| — | — |

| Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |

| ActivityManagerService | 负责四大组件的启动、切换、调度。 |

| PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |

| LightsService | 管理和显示背光LED |

| DisplayManagerService | 用来管理所有显示设备 |

| UserManagerService | 多用户模式管理 |

| SensorService | 为系统提供各种感应器服务 |

| PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |

| 核心服务 | |

| BatteryService | 管理电池相关的服务 |

| UsageStatsService | 收集用户使用每一个APP的频率、使用时常 |

| WebViewUpdateService | WebView更新服务 |

| 其他服务 | |

| CameraService | 摄像头相关服务 |

| AlarmManagerService | 全局定时器管理服务 |

| InputManagerService | 管理输入事件 |

| WindowManagerService | 窗口管理服务 |

| VrManagerService | VR模式管理服务 |

| BluetoothService | 蓝牙管理服务 |

| NotificationManagerService | 通知管理服务 |

| DeviceStorageMonitorService | 存储相关管理服务 |

| LocationManagerService | 定位管理服务 |

| AudioService | 音频相关管理服务 |

| … | …. |

比如要启动PowerManagerService则会调用如下代码:

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

SystemServiceManager的startService函数启动了PowerManagerService,startService函数如下所示。

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public T startService(Class serviceClass) {

final T service;

try {

Constructor constructor = serviceClass.getConstructor(Context.class);

service = constructor.newInstance(mContext);//1

} catch (InstantiationException ex) {

throw new RuntimeException("Failed to create service " + name

  • “: service could not be instantiated”, ex);

}

// Register it.

mServices.add(service);//2

// Start it.

try {

service.onStart();

} catch (RuntimeException ex) {

throw new RuntimeException("Failed to start service " + name

  • “: onStart threw an exception”, ex);

}

return service;

} finally {

Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

}

}

注释1处的代码用来创建SystemService,这里的SystemService是PowerManagerService,在注释2处将PowerManagerService添加到mServices中,这里mServices是一个存储SystemService类型的ArrayList。接着调用PowerManagerService的onStart函数启动PowerManagerService并返回,这样就完成了PowerManagerService启动的过程。

除了用mSystemServiceManager的startService函数来启动系统服务外,也可以通过如下形式来启动系统服务,以PackageManagerService为例:

mPackageManagerService = PackageManagerService.main(mSystemContext, installer,

mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

直接调用了PackageManagerService的main函数:

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public static PackageManagerService main(Context context, Installer installer,

boolean factoryTest, boolean onlyCore) {

// Self-check for initial settings.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值