SystemServer启动流程之SystemServer启动(二)
来源:互联网 发布:java读取文件 编辑:程序博客网 时间:2024/04/30 15:35
1、概述
上一篇文章中我们已经分析了Zogote进程的启动流程SystemServer启动流程之zygote启动(一),ZygoteInit.main方法做了四件事情,其中第三件事就是启动我们的system_server,system_server进程作为zygote的嫡长子,其重要性是不言而喻的,今天我们就来分析一下其启动流程。
2、源码分析
我们紧接着上一篇文章分析到的位置开始,上一篇文章我们分析到了ZygoteInit.main方法的第三步startSystemServer方法,此方法就是zogote用来fork新进程system_server的重要步骤。
(1)ZygoteInit.startSystemServer()
源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/** * Prepare the arguments and fork for the system server process. */ private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { long capabilities = posixCapabilitiesAsBits( OsConstants.CAP_BLOCK_SUSPEND, OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_RESOURCE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG ); /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* Request to fork the system server process */ //此处就是用于fork新进程system_server pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } //此处调用handleSystemServerProcess方法开始system_server进程的使命 handleSystemServerProcess(parsedArgs); } return true; }
Zogote将system_server进程fork出来后,将调用handleSystemServerProcess方法开始发挥system_server进程的作用了。
(2)ZygoteInit.handleSystemServerProcess()
源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/** * Finish remaining work for the newly forked system server process. */ private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { //关闭从zygote那里继承下来的socket closeServerSocket(); // set umask to 0077 so new files and directories will default to owner-only permissions. Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { //设置进程名为system_server Process.setArgV0(parsedArgs.niceName); } //获得SystemServer类的路径,用于后面执行SystemServer的main方法 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (parsedArgs.invokeWith != null) { //...... } else { ClassLoader cl = null; if (systemServerClasspath != null) { cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(cl); } /* * Pass the remaining arguments to SystemServer. */ //传入SystemServer类的加载器,执行zygoteInit方法 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */ }
此方法主要就是加载SystemServer类,然后执行RuntimeInit.zygoteInit方法,我们进入该方法。
(3)RuntimeInit.zygoteInit()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/** * The main function called when started through the zygote process. This * could be unified with main(), if the native code in nativeFinishInit() * were rationalized with Zygote startup.<p> * * Current recognized args: * <ul> * <li> <code> [--] <start class name> <args> * </ul> * * @param targetSdkVersion target SDK version * @param argv arg strings */ public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); //常规初始化设置 redirectLogStreams(); commonInit(); //native层初始化 nativeZygoteInit(); //调用Java层的main方法 applicationInit(targetSdkVersion, argv, classLoader); }
对此方法我们主要就分析一下nativeZygoteInit和applicationInit两个方法,我们进入nativeZygoteInit方法。
(4)RuntimeInit.nativeZygoteInit()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static final native void nativeZygoteInit();static AndroidRuntime* gCurRuntime = NULL;//这里需要重点说一下,AndroidRuntime会在startReg方法中预加载大量的JNIAndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) : mExitWithoutCleanup(false), mArgBlockStart(argBlockStart), mArgBlockLength(argBlockLength){ //这里将gCurRuntime变量赋值为AndroidRuntime对象 gCurRuntime = this;}static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz){ gCurRuntime->onZygoteInit();}
这是一个native层的方法,其在native层的实现方法是AndroidRuntime.cpp文件的nativeZygoteInit方法,进入该方法可以发现,这里的gCurRuntime就是AndroidRuntime的对象,而AndroidRuntime.cpp是没有onZygoteInit方法的,所以其调用的是其子类AppRuntime的onZygoteInit方法。
//frameworks/base/cmds/app_process/app_main.cppnamespace android { class AppRuntime : public AndroidRuntime { virtual void onZygoteInit() { // Re-enable tracing now that we're no longer in Zygote. atrace_set_tracing_enabled(true); sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); //启动一个线程用于Binder通信 proc->startThreadPool(); } }}
system_server调用完nativeZygoteInit之后,便于Binder通信系统建立了联系,这样system_server就能使用Binder进行通信了。
(5)RuntimeInit.applicationInit()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { // If the application calls System.exit(), terminate the process // immediately without running any shutdown hooks. It is not possible to // shutdown an Android application gracefully. Among other things, the // Android runtime shutdown hooks close the Binder driver, which can cause // leftover running threads to crash before the process actually exits. nativeSetExitWithoutCleanup(true); // We want to be fairly aggressive about heap utilization, to avoid // holding on to a lot of memory that isn't needed. VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args; try { args = new Arguments(argv); } catch (IllegalArgumentException ex) { Slog.e(TAG, ex.getMessage()); // let the process exit return; } // Remaining arguments are passed to the start class's static main //这里直接调用invokeStaticMain方法 invokeStaticMain(args.startClass, args.startArgs, classLoader); }
(6)RuntimeInit.invokeStaticMain()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/** * Invokes a static "main(argv[]) method on class "className". * Converts various failing exceptions into RuntimeExceptions, with * the assumption that they will then cause the VM instance to exit. * * @param className Fully-qualified class name * @param argv Argument vector for main() * @param classLoader the classLoader to load {@className} with */ private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; try { //加载com.android.server.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(); //判断main方法是否是public和static类型 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. */ //抛出MethodAndArgsCaller异常,将SystemServer的main方法传递过去 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
可以看到ZygoteInit.MethodAndArgsCaller是一个继承自Exception的类,invokeStaticMain最后并没有直接调用com.android.server.SystemServer的main 方法,而是抛出了一个ZygoteInit.MethodAndArgsCalle类型的异常。
那该异常是在哪里被捕获的呢?其实是在ZygoteInit的main方法中,也许之前我们都没注意。
public static void main(String argv[]) { try{ if ("start-system-server".equals(argv[i])) { startSystemServer = true; } if (startSystemServer) { startSystemServer(abiList, socketName); } }catch (MethodAndArgsCaller caller) { //捕获到异常后调用其run方法处理 caller.run(); } catch (RuntimeException ex) { closeServerSocket(); throw ex; }}
main函数中通过try-catch最终捕获到了MethodAndArgsCaller异常,并通过异常类的run函数来处理。
/** * Helper exception 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. */ public static class MethodAndArgsCaller extends Exception 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); } } }
至此,进入到SystemServer的Java世界啦,开始执行SystemServer的main方法,这里我们总结一下。
3、总结
这里主要讲述了如何从ZygoteInit.startSystemServer方法执行到SystemServer.main方法。
1、首先从ZygoteInit.startSystemServer()方法调用到RuntimeInit.zygoteInit()方法,主要是做zogote的初始化操作。
2、紧接着调用RuntimeInit.applicationInit()方法,此方法通过调用invokeStaticMain()方法来加载SystemServer类,并通过抛出MethodAndArgsCaller异常的方式让ZygoteInit.main()方法捕获处理。
3、ZygoteInit.main()方法通过catch捕获该异常后,通过其run方法的 mMethod.invoke()来执行SystemServer的main方法。
- SystemServer启动流程之SystemServer启动(二)
- SystemServer启动流程之SystemServer分析(三)
- Android SystemServer 启动流程
- SystemServer 启动流程
- SystemServer进程启动流程
- Android SystemServer 启动流程
- SystemServer启动流程之Zygote启动(一)
- Android源码解析之(九)-->SystemServer进程启动流程
- SystemServer启动流程之WatchDog分析(四)
- Android源码解析之(九)-->SystemServer进程启动流程
- (N)Telephony分析(二)之SystemServer启动
- android启动之SystemServer启动
- android启动之SystemServer启动
- android 启动流程到SystemServer
- Android启动过程之SystemServer
- Android源码基础解析之SystemServer进程启动流程
- Android启动流程分析(十二) SystemServer
- Android5 Zygote 与 SystemServer 启动流程分析
- web.xml中<security-constraint>和四种认证类型
- Java与算法之(11) - 合并排序
- Yii2 分页 搜索变红
- jvm 内存溢出
- 计算机图形学(三)_图元的属性_11_ 凸多边形的扫描线填充
- SystemServer启动流程之SystemServer启动(二)
- AngularJS主要组成部分及小实例
- Spring Data JPA
- 旋转字符串
- NGUI使用自定义的中文字体??解决办法1!!
- Linux命令解析--wc 最好用的统计命令
- 顺序表应用7:最大子段和之分治递归法
- proxool配置
- sql map 索引插入的问题 防止多条重复操作返回id重复