【Android 源码学习】SystemServer启动原理
Android 源码学习 SystemServer启动原理
望舒课堂 SystemServer进程启动原理学习记录整理。
参考文章:
Android系统启动流程(三)解析SyetemServer进程启动过程
SystemServer简介
SystemServer是Android系统的核心之一,大部分Android提供的服务都在该进程中。
Zygote处理SystemServer进程
zygote处理SystemServer时序图
ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
zygoteInit的关键代码:
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {....../* Request to fork the system server process */// 创建子进程(SystemServer进程)pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);....../* For child process */// 当前代码逻辑运行在子进程中if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}zygoteServer.closeServerSocket();// 处理SystemServer进程return handleSystemServerProcess(parsedArgs);......}private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {if (parsedArgs.mInvokeWith != null) {......} else {ClassLoader cl = null;if (systemServerClasspath != null) {// 加载系统类cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);Thread.currentThread().setContextClassLoader(cl);}/** Pass the remaining arguments to SystemServer.*/return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);}public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();// 启动Binder线程池ZygoteInit.nativeZygoteInit();// 进入SystemServer的main方法return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);}private static final native void nativeZygoteInit();}
nativeZygoteInit();调用的是native方法,位于AppRuntime
/frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{/*** JNINativeMethod 是在/libnativehelper/include_jni/jni.h 中定义的struct * typedef struct {* const char* name; //java方法名* const char* signature;//java方法签名信息* void* fnPtr;//java方法在JNI中对应的函数* } JNINativeMethod;*/const JNINativeMethod methods[] = {{ "nativeZygoteInit", "()V",(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },};return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",methods, NELEM(methods));
}
static AndroidRuntime* gCurRuntime = NULL;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{gCurRuntime->onZygoteInit();
}
onZygoteInit 是虚方法 具体实现在AndroidRuntime的子类AppRuntime中
/frameworks/base/core/jni/include/android_runtime/AndroidRuntime.h
/*** This gets called after the JavaVM has initialized after a Zygote* fork. Override it to initialize threads, etc. Upon return, the* correct static main will be invoked.*/virtual void onZygoteInit() { }
具体代码还是在app_main中
/frameworks/base/cmds/app_process/app_main.cpp
class AppRuntime : public AndroidRuntime{......virtual void onZygoteInit(){sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");// 启动binder线程池proc->startThreadPool();}......
}
RuntimeInit.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
ZygoteInit.zygoteInit 方法 返回RuntimeInit.applicationInit
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {......// Remaining arguments are passed to the start class's static mainreturn findStaticMain(args.startClass, args.startArgs, classLoader);}protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {Class<?> cl;try {// 反射得到SystemServer类cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className,ex);}Method m;try {// 获取 main 方法m = cl.getMethod("main", new Class[] { String[].class });} 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);}/** This throw gets caught in ZygoteInit.main(), which responds* by invoking the exception's run() method. This arrangement* clears up all the stack frames that were required in setting* up the process.*/return new MethodAndArgsCaller(m, argv);}/*** Helper class which holds a method and arguments and can call them. This is used as part of* a trampoline to get rid of the initial process setup stack frames.*/static class MethodAndArgsCaller implements Runnable {/** method to call */private final Method mMethod;/** argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {try {// 调用SystemServer的main方法mMethod.invoke(null, new Object[] { mArgs });} catch (IllegalAccessException ex) {throw new RuntimeException(ex);} catch (InvocationTargetException ex) {Throwable cause = ex.getCause();if (cause instanceof RuntimeException) {throw (RuntimeException) cause;} else if (cause instanceof Error) {throw (Error) cause;}throw new RuntimeException(ex);}}}
ZygoteInit 执行回调
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {......zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {//fock SystemServer进程Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);// {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.if (r != null) {r.run();//执行system_serverreturn;}Log.i(TAG, "Accepting command socket connections");// The select loop returns early in the child process after a fork and// loops forever in the zygote.// 轮询,等待AMS请求caller = zygoteServer.runSelectLoop(abiList);} catch (Throwable ex) {Log.e(TAG, "System zygote died with exception", ex);throw ex;} finally {if (zygoteServer != null) {zygoteServer.closeServerSocket();}}// We're in the child process and have exited the select loop. Proceed to execute the// command.if (caller != null) {caller.run();}}}
解析SystemServer进程
/frameworks/base/services/java/com/android/server/SystemServer.java
经过ZygoteInit启动SystemServer启动,进入SystemServer的main方法
关键方法:
public static void main(String[] args) {new SystemServer().run();}private void run() {......// Create the system service manager.mSystemServiceManager = new SystemServiceManager(mSystemContext);mSystemServiceManager.setStartInfo(mRuntimeRestart,mRuntimeStartElapsedTime, mRuntimeStartUptime);//将Service保存在本进程中,保存的Service在同一进程LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);......// Start services.try {t.traceBegin("StartServices");// 启动引导服务startBootstrapServices(t);// 启动核心服务startCoreServices(t);// 启动其他服务startOtherServices(t);} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;} finally {t.traceEnd(); // StartServices}......}
系统服务
列举部分系统服务。
表格截取刘望舒的文章。
引导服务 | 作用 |
---|---|
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 | 音频相关管理服务 |
SystemServiceManager.java
SystemServer里调用SystemServiceManager的startService来启动相应服务
例如DisplayManagerService
// Display manager is needed to provide display metrics before package manager// starts up.t.traceBegin("StartDisplayManager");mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);t.traceEnd();
SystemServiceManager
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
关键代码:
public void startService(@NonNull final SystemService service) {// Register it.mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {service.onStart();} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + service.getClass().getName()+ ": onStart threw an exception", ex);}warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
总结
SystemServer进程被创建后,主要做了如下工作:
- 启动Binder线程池,这样就可以与其他进程进行通信
- 创建SystemServiceManager用于对系统的服务创建、启动和生命周期管理。
- 启动各种系统服务
【Android 源码学习】SystemServer启动原理相关推荐
- android源码学习-Toast实现原理讲解
前言: 前些日志QQ群有朋友发了一个Toast的崩溃日志.Toast如此简单的用法怎么会崩溃呢?所以顺便就学习了一下Toast在源码中的实现,不算复杂,但内容挺多的,这里就来分享一下,方便读者. 一. ...
- android源码学习- APP启动流程(android12源码)
前言: 百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分).所以我结合网上现有的文章,以及源码的阅读和调试, ...
- 【Android 源码学习】Zygote启动原理
Android 源码学习 Zygote启动原理 望舒课堂 Zygote进程启动原理学习记录整理. Zygote简介 Zygote是进程在init进程启动时创建的,进程本身是app_process,来源 ...
- 【Android 源码学习】 init启动
目录 Android 源码学习 init启动 从main.cpp开始 init.cpp 部分逻辑 init启动zygote 属性服务 总结 Android 源码学习 init启动 Android 11 ...
- Android源码学习之浅析SystemServer脉络
在之前的博文中<Android源码学习之如何创建使用JNI>和<Android源码学习之如何使用eclipse+NDK>中,浅谈了如何创建使用JNI和如何利用NDK工具开发创建 ...
- 【Android 源码学习】系统架构和启动流程
Android 源码学习 系统架构和启动流程 望舒课堂 学习记录整理.以及以下参考文章的整理汇总.便于我个人的学习记录. 感谢IngresGe,Gityuan的精彩文章.为我们这些初探android系 ...
- Android源码编译及启动模拟器
Android源码编译及启动模拟器 源码下载 (1)更改下载源 (2)安装源码下载工具 (3)下载源码 (4)安装环境依赖 源码编译 启动模拟器 源码下载 Ubuntu18.0 (1)更改下载源 源码 ...
- 【Android 源码学习】SharedPreferences 源码学习
第一章:SharedPreferences 源码学习 文章目录 第一章:SharedPreferences 源码学习 Android SharedPreferences的缺陷 MMKV.Jetpack ...
- Android源码学习之工厂方法模式应用
主要内容: 工厂方法模式定义 工厂方法模式优势 工厂方法模式在Android源码中的应用 一.工厂方法模式定义 工厂方法模式定义: Define an interface for creating a ...
最新文章
- Linux系统端口聚合技术bonding
- python格式化字符串漏洞_Python新型字符串格式漏洞分析及解决方案
- 暴力枚举也不能没有底线(洛谷P1003题题解,Java语言描述)
- ldconfig和ldd用法
- python返回函数值并退出函数_Python函数的返回值和作用域
- IDEA运行项目出现Caused by:java.lang.OutOfMemoryError: PermGen space
- NUC1170 加农炮
- floyd算法_常用十大算法(九)— 弗洛伊德算法
- 如果你知道10条以上,你就和我一样渊博了
- 外挂辅助技术-计算怪物与玩家的距离
- 安装PostgreSQL客户端
- c语言jni调用外部函数,(转)JNI调用C函数
- 渗透测试-SQL注入之宽字节注入
- php利用表格敬将所选择的数据显示出来,单元格下拉筛选设置/Excel对筛选后的单元格进行下拉填充...
- ios python 越狱_iOS越狱--USB连接SSH
- 正负数在计算机中的表示(原码反码补码)及位运算
- dede织梦系统接入熊掌号推送api,完整详细教程
- 使用Python绘制股票交易图形
- 揭秘:恒生电子到底是干什么的
- IP冲突解决解决方法
热门文章
- OMG Data Distribution Service(DDS)规范解读-Part1
- oracle 二进制与运算,ORACLE使用函数对二进制、十进制、十六进制数互相转换
- 5 Redis高可用方案
- 1024程序员节|基于Springboot实现爱心捐赠管理系统
- Cookies 必须启用才能登入 phpmyadmin的问题
- 【2018/10/16测试T3】长者
- Android添加系统service
- MATLAB三维绘图基础meshgrid函数的用法解析
- java printwriter乱码_HttpServletResponse PrintWriter中文乱码解决方法
- 算法整理八——回溯算法