在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的。Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中。
一、在init.rc脚本文件中:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 666 onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd
service zygote init进程创建一个名为"zygote"的进程
/system/bin/app_process zygote进程要执行的程序
-Xzygote 传递给VM的选项,-Xzygote 选项用来区分要在虚拟机中运行的类是Zygote,还是在Zygote中运行的其他Android应用程序。
/system/bin 运行目录参数/system/bin 保存到 parentDir 变量中。
--zygote 用来指定加载到虚拟机中类的名称,表示加载com.android.internel.os.ZygoteInit类。
--start-system-server 作为选项传递给生成的类,用于启动运行System server。
socket zygote stream 666 套接字的名称,种类,访问权限
Zygote进程要执行的程序便是system/bin/app_process了,在frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。
int main(int argc, const char* const argv[]) { // These are global variables in ProcessState.cpp mArgC = argc; mArgV = argv; mArgLen = 0; for (int i=0; i<argc; i++) { mArgLen += strlen(argv[i]) + 1; } mArgLen--; AppRuntime runtime; const char* argv0 = argv[0]; // Process command line arguments // ignore argv[0] argc--; argv++; // Everything up to '--' or first non '-' arg goes to the vm int i = runtime.addVmArguments(argc, argv);// // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; const char* parentDir = NULL; const char* niceName = NULL; const char* className = NULL; while (i < argc) { const char* arg = argv[i++];//运行目录参数/system/bin 保存到 parentDir 变量中 if (!parentDir) { parentDir = arg; } else if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = "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 = arg + 12; } else { className = arg; break; } } if (niceName && *niceName) { setArgv0(argv0, niceName); set_process_name(niceName); } runtime.mParentDir = parentDir; if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : ""); //调用AppRuntime的start()成员函数,生成并初始化虚拟机,然后将ZygoteInit()类加载到虚拟机中,执行其中的main()方法。 } else if (className) { // Remainder of args get passed to startup class main() runtime.mClassName = className; runtime.mArgC = argc - i; runtime.mArgV = argv + i; runtime.start("com.android.internal.os.RuntimeInit", application ? "application" : "tool"); } 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; } }
此函数主要工作:分析传递给虚拟机的参数,并保存到AppRuntime类的对象中,然后加载对象,调用对象的main()方法。
二、进入到AndroidRuntime.cpp 中start()函数中
void AndroidRuntime::start(const char* className, const char* options) { LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n", className != NULL ? className : "(unknown)"); blockSigpipe(); /* * 'startSystemServer == true' means runtime is obsolete and not run from * init.rc anymore, so we print out the boot start event here. */ if (strcmp(options, "start-system-server") == 0) { /* 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"); //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); /* start the virtual machine *///创建java虚拟机 JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) {//mJavaVM 生成的JavaVM类的接口指针,env JNIEnv类的接口指针,方便访问虚拟机 return; } onVmCreated(env); /* * Register android functions. */ if (startReg(env) < 0) {//注册虚拟机要使用的JNI函数,以后运行在虚拟机中的JAVA类就可以调用本地函数。 LOGE("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; jstring optionsStr; stringClass = env->FindClass("java/lang/String"); assert(stringClass != NULL); strArray = env->NewObjectArray(2, stringClass, NULL); assert(strArray != NULL); classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); optionsStr = env->NewStringUTF(options); env->SetObjectArrayElement(strArray, 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) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");//在类中查找形式参数为String数组且返回值为void的main()静态方法。 if (startMeth == NULL) { LOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { env->CallStaticVoidMethod(startClass, startMeth, strArray);//找到次方法,调用此方法,此时程序的执行转到虚拟机中运行的java应用程序上。 //进入到ZygoteInit.java--ZygoteInit::main()方法中 ... ... } } ... ... }
三、进入到ZygoteInit.java--ZygoteInit::main()方法中
public static void main(String argv[]) { try { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); registerZygoteSocket();//1、绑定套接字, 接受新android应用程序运行请求 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload();//2、加载 android application framework 使用的类和资源 , EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); // Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup gc(); // If requested, start system server directly from Zygote if (argv.length != 2) { throw new RuntimeException(argv[0] + USAGE_STRING); } if (argv[1].equals("start-system-server")) { startSystemServer();//3、运行systemserver } else if (!argv[1].equals("")) { throw new RuntimeException(argv[0] + USAGE_STRING); } Log.i(TAG, "Accepting command socket connections"); if (ZYGOTE_FORK_MODE) { runForkMode(); } else { runSelectLoopMode();//4、处理新android应用程序运行请求 } closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } }
首先分析第一点:registerZygoteSocket();//1、绑定套接字, 接受新android应用程序运行请求
private static void registerZygoteSocket() { if (sServerSocket == null) { int fileDesc; try { String env = System.getenv(ANDROID_SOCKET_ENV);//获取套接字的文件描述符。它记录在ANDROID_SOCKET_zygote环境变量中。 fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException( ANDROID_SOCKET_ENV + " unset or invalid", ex); } try { sServerSocket = new LocalServerSocket( createFileDescriptor(fileDesc));//使用套接字文件描述符创建LocalServerSocket的实例,将其与/dev/socket/zygote绑定在一起 } catch (IOException ex) { throw new RuntimeException( "Error binding to local socket '" + fileDesc + "'", ex); } } }
第二点:加载 android application framework 使用的类和资源
static void preload() { preloadClasses(); preloadResources(); } private static void preloadClasses() { final VMRuntime runtime = VMRuntime.getRuntime(); InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream( PRELOADED_CLASSES);//获取一个输入流,以便读取proloaded-classes文件中的类 ,framework/base/preloafed-classes文件。 ... ... try { BufferedReader br = new BufferedReader(new InputStreamReader(is), 256);//创建BufferedReader对象,并读取文件中的内容。 ... ... line = line.trim();//忽略文件中的注释和空行,读取下一行 if (line.startsWith("#") || line.equals("")) { continue; } ... ... Class.forName(line);//将读取到得类动态的加载到内存中 ... ... }
第三点:运行systemserver,在ZygoteInit.java中startSystemServer()方法中
private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { /* 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,3001,3002,3003,3006,3007", "--capabilities=130104352,130104352", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer",//用于指定systemserver类 }; ... ... pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities);//创建新进程,并运行systemserver ... ... /* For child process */ if (pid == 0) { handleSystemServerProcess(parsedArgs);//在生成的systemserver进程中运行com.android.server.SystemServer类的main()方法 } ... ... }
进入handleSystemServerProcess()中
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { ... ... RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs); ... ... }
进入RuntimeInit.java 中zygoteinit方法中
public static final void zygoteInit(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller { if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); redirectLogStreams(); commonInit(); zygoteInitNative();//1、native层初始化 applicationInit(targetSdkVersion, argv); }
在进入applicationInit()中
private static void applicationInit(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller { ... ... invokeStaticMain(args.startClass, args.startArgs); //2、调用startclass,也就是com.android.server.SystemServer类的main()函数 }
分析上面两点:
1、native层初始化 zygoteInitNative()
public static final native void zygoteInitNative();他是一个本地函数,经过JNI调用AndroidRuntime.cpp中的
static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz) { gCurRuntime->onZygoteInit(); }
gCurRuntime是指什么?
gCurRuntime
在app_main.cpp main()函数中
int main(int argc, const char* const argv[]) { ... AppRuntime runtime; ... ... }
看其定义
class AppRuntime : public AndroidRuntime
继承AndroidRuntime类
static AndroidRuntime* gCurRuntime = NULL; //为全局变量
AndroidRuntime.cpp中
AndroidRuntime::AndroidRuntime() { SkGraphics::Init(); ... ... gCurRuntime = this; // gCurRuntime 被设置为AndroidRuntime对象自己 }
故:此时启动App_main.cpp中onZygoteInit()函数
virtual void onZygoteInit() { sp<ProcessState> proc = ProcessState::self(); LOGV("App process: starting thread pool.\n"); proc->startThreadPool();//启动一个线程,用于binder通信 }
2、invokeStaticMain(args.startClass, args.startArgs)
调用startclass,也就是com.android.server.SystemServer类的main()函数
private static void invokeStaticMain(String className, String[] argv) throws ZygoteInit.MethodAndArgsCaller { ... ... m = cl.getMethod("main", new Class[] { String[].class }); //找到com.android.server.SystemServer类的main()函数 ... ... throw new ZygoteInit.MethodAndArgsCaller(m, argv);//抛出一个异常 }
将在ZygoteInit的main函数中截获到,
ZygoteInit.java的main()中
public static void main(String argv[]) { ... ... try { ... ... if (argv[1].equals("start-system-server")) { startSystemServer();//运行systemserver 在此中抛出一个异常 } else if (!argv[1].equals("")) { throw new RuntimeException(argv[0] + USAGE_STRING); } } catch (MethodAndArgsCaller caller) { caller.run(); ... ... }
将进入MethodAndArgsCaller 的run函数
public void run() { try { //mMethod为com.android.server.SystemServer的main()函数 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { ... ... }
现在进入到SystemServer.java的main中
public static void main(String[] args) { ... ... VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); System.loadLibrary("android_servers");//加载android_servers本地库文件 init1(args); }
进入init1()为本地方法,将进入
native public static void init1(String[] args);
com_android_server_SystemServer.cpp中的
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz) { system_init(); }
extern "C" int system_init();将调用system_init.cpp中的system_init(0函数
extern "C" status_t system_init(){ ... ... property_get("system_init.startsurfaceflinger", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { // Start the SurfaceFlinger SurfaceFlinger::instantiate();//注册本地服务 } ...... jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");//调用init2()方法 ... ... }
init2()方法
public static final void init2() { Slog.i(TAG, "Entered the Android system server!"); Thread thr = new ServerThread(); thr.setName("android.server.ServerThread"); thr.start();/创建一个线程android.server.ServerThread,并启动它 }
第四点:处理新android应用程序运行请求 runSelectLoopMode()
private static void runSelectLoopMode() throws MethodAndArgsCaller { ... ... fds.add(sServerSocket.getFileDescriptor());//将套接字的描述符添加到描述符数组中 ...... boolean done; done = peers.get(index).runOnce();//处理新连接的输入输出套接字,并生成新的android应用程序。 ... ... }
进入zygoteconnection.java中的runonce()中
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { .... ... args = readArgumentList();//读取请求信息,请求信息包含创建新进程的参数选项 ... ... parsedArgs = new Arguments(args);//分析请求信息中的字符数组,为运行进程设置好各个选项 ... ... pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits);//创建新进程 if (pid == 0) { // in child IoUtils.closeQuietly(serverPipeFd);// serverPipeFd = null; handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);//加载新进程所需的类,并调用类的main()方法。启动新的应用程序。子进程处理 // should never get here, the child is expected to either // throw ZygoteInit.MethodAndArgsCaller or exec(). return true; } else { // in parent...pid of < 0 means failure IoUtils.closeQuietly(childPipeFd); childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);//zygote进程 } }
进入到新进程创建的子进程中的处理 handleChildProc()
ZygoteConnection.java private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { ... ... RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs); ... ... }
在进入到RuntimeInit.java中的zygoteinit()方法中最终调用了
invokeStaticMain(args.startClass, args.startArgs);函数,前面已经分析。
android 启动过程
Android从Linux系统启动有4个步骤;
(1) init进程启动
(2) Native服务启动
(3) System Server,Android服务启动
(4) Home启动
SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上。
第一步:在上面,讲到了启动systemserver的过程
SystemServer.java的main函数
public static void main(String[] args) { ... ... System.loadLibrary("android_servers"); init1(args); }
启动init1()函数,
native public static void init1(String[] args);
Init1()是一个本地函数,将会进入到
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz) { system_init(); }
调用extern "C" int system_init();
会进入到System_init.cpp中的system_init中
extern "C" status_t system_init() { ... ... jclass clazz = env->FindClass("com/android/server/SystemServer"); if (clazz == NULL) { return UNKNOWN_ERROR; } jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V"); ... ... }
初始化一些服务后,会调用com/android/server/SystemServer类中的init2()方法
Systemserver.java函数init2()
public static final void init2() { Slog.i(TAG, "Entered the Android system server!"); Thread thr = new ServerThread();//创建了一个ServerThread线程 thr.setName("android.server.ServerThread"); thr.start(); }
许多android framework服务都是在这个线程中注册的,可以查看其run方法。
如:ServiceManager,ActivityManagerService,PackageManagerService等。
第二步:
在run中将启动ActivityManagerService服务,
public void run() { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); Looper.prepare(); ... ... Slog.i(TAG, "Activity Manager"); context = ActivityManagerService.main(factoryTest);//1、 ... ... ActivityManagerService.setSystemProcess();//2、 mContentResolver = context.getContentResolver(); ... ... ActivityManagerService.self().systemReady(new Runnable() {//3、 ... ... } }
在上面的run方法中
1、在main()方法中通过AThread线程对象来内部创建了一个ActivityManagerService实例,最后将其保存到成员变量mSelf 中,然后初始化其它成员变量。
2、
public static void setSystemProcess() { try { ActivityManagerService m = mSelf; //将ActivityManagerService注册到server manager中区,可以通过ServiceManager.getService接口来访问这个全局唯一的ActivityManagerService实例。 ServiceManager.addService("activity", m); ServiceManager.addService("meminfo", new MemBinder(m)); ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(m)); } ServiceManager.addService("permission", new PermissionController(m)); ApplicationInfo info = mSelf.mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info); //把在应用程序框架层下面的android包加载进来 ... ... }
3、最后调用systemReady方法
在ActivityManagerServcie.java
public void systemReady(final Runnable goingCallback) { synchronized(this) { ... ... mMainStack.resumeTopActivityLocked(null);//启动Home应用程序 ... ... } }
第三步:
1、将会进入到ActivityStack.java resumeTopActivityLocked()中
final boolean resumeTopActivityLocked(ActivityRecord prev) {
ActivityRecord next = topRunningActivityLocked(null);//返回的是当前系统Activity堆栈最顶端的Activity,此时还没有activity启动,故为null。
... ... if (next == null) { // There are no more activities! Let's just start up the // Launcher... if (mMainStack) { return mService.startHomeActivityLocked(); } } ... ... }
2、进入到ActivityManagerService.java中的startHomeActivityLocked()
boolean startHomeActivityLocked() { if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL && mTopAction == null) { return false; } Intent intent = new Intent( mTopAction, mTopData != null ? Uri.parse(mTopData) : null); intent.setComponent(mTopComponent); if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { intent.addCategory(Intent.CATEGORY_HOME); } ActivityInfo aInfo = intent.resolveActivityInfo(mContext.getPackageManager(), STOCK_PM_FLAGS);//向PackageManagerService查询Category类型为HOME的Activity。(AndroidManifest.xml中) if (aInfo != null) { intent.setComponent(new ComponentName( aInfo.applicationInfo.packageName, aInfo.name)); // Don't do this if the home app is currently being // instrumented. ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid);//第一次启动这个Activity,故app为null。 if (app == null || app.instrumentationClass == null) { intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo, null, null, 0, 0, 0, false, false, null);//调用此函数启动这个Activity。 } } return true; }
第四步、
调用此startActivityLocked函数后,就会启动com.android.launcher2.Launcher,然后调用它的Oncreate()方法。