(N)Telephony分析(二)之SystemServer启动
来源:互联网 发布:侧面导航栏网站源码 编辑:程序博客网 时间:2024/05/21 10:24
已经了解了zygote的启动,那么接着zygote启动,往后继续分析
zygote在启动的时候,启动的是一个进程,为/system/bin/app_process,而这个app_process的进程,是在app_main.cpp文件中启动的,查看其main函数
frameworks/base/cmds/app_process/app_main.cpp文件
int main(int argc, char* const argv[]){ ...... // Leo, 定义AppRuntime AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ...... // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. // Leo, 根据在zygote启动的init.zygote32.rc文件中的数据配置参数 while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; // zygote } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } Vector<String8> args; if (!className.isEmpty()) { // We're not in zygote mode, the only argument we need to pass // to RuntimeInit is the application argument. // // The Remainder of args get passed to startup class main(). Make // copies of them before we overwrite them with the process name. args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i); } else { ...... } if (!niceName.isEmpty()) { runtime.setArgv0(niceName.string());
// Leo,将app_process进程名称改为zygote set_process_name(niceName.string()); } if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else { fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); return 10; }从app_main.cpp文件的main函数中,我们可以看到,
1. 在刚开始,通过zygote启动时传入的参数
2. 将app_process的进程名称改为zygote进程
3. 配置一下AppRuntime的参数值
4. 由于传入的zygote为true,因此会start ZygoteInit方法
那么看看runtime的start方法
AndroidRuntime.cpp文件
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){ ALOGD(">>>>>> START %s uid %d <<<<<<\n", className != NULL ? className : "(unknown)", getuid()); static const String8 startSystemServer("start-system-server"); /* * 'startSystemServer == true' means runtime is obsolete and not run from * init.rc anymore, so we print out the boot start event here. */ for (size_t i = 0; i < options.size(); ++i) { if (options[i] == startSystemServer) { /* track our progress through the boot sequence */ const int LOG_BOOT_PROGRESS_START = 3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } } const char* rootDir = getenv("ANDROID_ROOT"); if (rootDir == NULL) { rootDir = "/system"; if (!hasDir("/system")) { LOG_FATAL("No root directory specified, and /android does not exist."); return; } setenv("ANDROID_ROOT", rootDir, 1); } //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; // Leo, 创建虚拟机的一系列配置 if (startVm(&mJavaVM, &env, zygote) != 0) { return; } onVmCreated(env); /* * Register android functions. */ // Leo, 注册JNI if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } /* * We want to call main() with a String array with arguments in it. * At present we have two arguments, the class name and an option string. * Create an array to hold them. */ jclass stringClass; jobjectArray strArray; jstring classNameStr; stringClass = env->FindClass("java/lang/String"); assert(stringClass != NULL); strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); assert(strArray != NULL); // Leo,classname传入的为com.android.internal.os.ZygoteInit classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); for (size_t i = 0; i < options.size(); ++i) { jstring optionsStr = env->NewStringUTF(options.itemAt(i).string()); assert(optionsStr != NULL); env->SetObjectArrayElement(strArray, i + 1, optionsStr); } /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { // Leo,找到main函数 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { // Leo,调用com.android.internal.os.ZygoteInit的main方法 env->CallStaticVoidMethod(startClass, startMeth, strArray);#if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env);#endif } } free(slashClassName); ALOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) ALOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) ALOGW("Warning: VM did not shut down cleanly\n");}从AndroidRuntime的start方法中,我们可以知道,在这个方法中,主要是做了
1. startVm,创建虚拟机
2. startReg,注册JNI环境
3. 调用ZygoteInit方法的main函数
前两条,暂不分析,由此,我们进入了JAVA世界
ZygoteInit.java文件
public static void main(String argv[]) { ...... try { ...... boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { // Leo,从zygote处传入的参数,此地为true startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } ...... // Leo, 注册zygote的socket registerZygoteSocket(socketName); ...... // Leo,加载一些class/resources等 preload(); ...... // Leo,开启SystemServer世界 if (startSystemServer) { startSystemServer(abiList, socketName); } ...... // Leo, runSelectLoop(abiList); closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (Throwable ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; }}从这部分代码中可以看到,调用startSystemServer来启动SystemServer
private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ...... /* Hardcoded command line to start the system server */ // Leo,SystemServer的各个参数 String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { // Leo,写入各个参数 parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* Request to fork the system server process */ // Leo,fork一个进程,这个进程应该就是SystemServer吧 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) { ...... // Leo, SystemServer的具体作用 handleSystemServerProcess(parsedArgs); } return true;}从这边可以看到,设置SystemServer的一些参数,然后通过Zygote的forkSystemServer方法,创建一个nice_name为system_server的进程,自此,SystemServer就被创建了,那么SystemServer进程的具体作用是什么呢
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller {// Leo, 关闭与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) { Process.setArgV0(parsedArgs.niceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); } if (parsedArgs.invokeWith != null) { String[] args = parsedArgs.remainingArgs; // If we have a non-null system server class path, we'll have to duplicate the // existing arguments and append the classpath to it. ART will handle the classpath // correctly when we exec a new process. if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); } WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); } else { ClassLoader cl = null; if (systemServerClasspath != null) { cl = createSystemServerClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } /* * Pass the remaining arguments to SystemServer. */ // Leo,调用RuntimeInit的zygoteInit方法 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */}此处先关闭与zygote的socket通信,独立完成自己的任务,然后调用了RuntimeInit的zygoteInit方法
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(); // Leo,做一些常规的初始化操作 commonInit(); // Leo,初始化native层 nativeZygoteInit(); // Leo, 初始化一些应用?我们分析看看~ applicationInit(targetSdkVersion, argv, classLoader); }在这个方法中,可以看到做了一些初始化操作,我们直接看最后一个方法
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { ...... // Remaining arguments are passed to the start class's static main invokeStaticMain(args.startClass, args.startArgs, classLoader);}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; try { // Leo, classname为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 { 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. */ throw new ZygoteInit.MethodAndArgsCaller(m, argv); }从这个方法中可以看到,取出SystemServer的main方法,然后抛出ZygoteInit.MethidAndArgsCaller异常,那么在哪儿catch这个异常的呢?追溯到前面,可以看到,在ZygoteInit的main函数中,有catch这个异常,并且直接调用了这个caller的run方法,因此,进入MethodAndArgsCaller的run方法
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 { 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的main方法,自此,进入了SystemServer的java世界
阅读全文
0 0
- (N)Telephony分析(二)之SystemServer启动
- SystemServer启动流程之SystemServer启动(二)
- (N)Telephony分析(一)之zygote进程启动
- (N)Telephony分析(三)之PhoneApp启动
- SystemServer启动流程之SystemServer分析(三)
- (N)Telephony分析(四)之PhoneApp初始化分析
- SystemServer启动流程之WatchDog分析(四)
- (N)Telephony分析(五)之DcTracker的初始化
- (N)Telephony分析(七)之DataConnection建立
- Android Telephony分析(二)--- RegistrantList详解
- (N)Telephony分析(六)之DcTracker的requestNetwork分析
- SystemServer启动流程之Zygote启动(一)
- SystemServer进程源码分析之二
- Zygote,SystemServer启动分析
- zygote,systemserver 启动分析
- Android源码解析之(九)-->SystemServer进程启动流程
- Android源码解析之(九)-->SystemServer进程启动流程
- android启动之SystemServer启动
- Android6.0和7.0新特性分析
- cartographer源码分析(18)-sensor-compressed_point_cloud
- 不要重载&& ||和,操作符
- 设计模式之抽象工厂模式
- linux编译出现/usr/bin/ld: 找不到 -lopencv_dep_cudart 的问题解决
- (N)Telephony分析(二)之SystemServer启动
- HDU6055 Regular polygon【哈希】
- iOS url链接重定向的方法
- char,short ,int ,long,long long,unsigned long long数据范围
- mysql 两个字段内容互换
- CS231n课程笔记翻译6:神经网络笔记 part1
- NodeMCU文档中文翻译 8 Websocket模块
- fastjson的JSONArray和JSONObject
- 从今天开始