简述

Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程。

Zygote就是进程init启动起来的。Android中所有应用程序进程,以及运行系统关键服务的System进程都是由Zygote创建的。它通过复制自身的形式创建其它进程。Zygote在启动时会在内部创建一个虚拟机实例,因此,通过复制Zygote得到的其它应用程序进程和System进程都可以快速地在内部获得一个虚拟机地拷贝。Zygote启动完成后就立即将System进程启动,以便各种关键服务被启动运行。

Zygote的启动

它以服务的形式被启动。

创建虚拟机

进程内创建一个虚拟机实例,并注册一系列JNI方法。

frameworks/base/core/jni/AndroidRuntime.cpp

/* start the virtual machine. */
startVM(&mJavaVM, &env);
/* Register android functions. */
startReg(env);

接下来执行“com.android.internal.os.ZygoteInit”Java类的main方法继续执行启动。

ZygoteInit.main

package com.android.internal.os;
import android.net.LocalServerSocket;
...
public class ZygoteInit {
private static LocalServerSocket sServerSocket; public static void main(String argv[]) {
...
registerZygoteSocket();
...
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
...
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
...
closeServerSocket();
...
}
}

创建Socket

Zygote调用registerZygoteSocket();创建一个LocalServerSocket sServerSocket的Server端Socket,等待以后运行在System进程中的服务ActivityManagerService创建的Client端Socket连接,然后通过Socket进程间通信通知Zygote创建新的应用程序进程。

创建System进程

/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--capabilities=130104352,130104352",
"--rlimit=8,",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
...
ZygoteConnection.Arguments parsedArgs = null;
int pid; try {
parsedArgs = new ZygoteConnection.Arguments(args); /* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, rlimits,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
} /* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
} return true;
}

变量args保存启动System进程的参数。

Zygote.forkSystemServer()复制当前进程来创建子进程。

handleSystemServerProcess()继续处理System进程的启动。

轮询等待AMS请求创建App进程

private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4]; fds.add(sServerSocket.getFileDescriptor());
peers.add(null); while (true) {
...
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
} if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce(); if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
} /**
* Waits for and accepts a single command connection. Throws
* RuntimeException on failure.
*/
private static ZygoteConnection acceptCommandPeer() {
try {
return new ZygoteConnection(sServerSocket.accept());
} catch (IOException ex) {
throw new RuntimeException(
"IOException during accept()", ex);
}
}

无限循环,等待来自AMS创建的Socket连接。

sServerSocket在fds[0]位置。

每当accept()返回一个连接后,将对应此连接的newPeer.getFileDesciptor()套接字描述添加到fds(第0位置后),下一次读取到数据时,若在fds[0]以后的,说明是前面的newPeer连接收到的AMS的创建新应用程序进程的请求。

runOnce()用来处理AMS创建新应用程序进程的请求。

System进程的启动

ZygoteInit.handleSystemServerProcess()执行System进程的启动操作。

ZygoteInit.handleSystemServerProcess()

private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); /*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}

Zygote复制自身创建的子进程做为System进程,这样它得到了Zygote的Server Socket,但是用不到,所以第一句closeServerSocket()关闭此套接字。

RuntimeInit.zygoteInit

package com.android.internal.os;

public class RuntimeInit {
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
...
commonInit();
zygoteInitNative();
...
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg]; System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
}

zygoteInitNative()在System进程中启动一个Binder线程池。

RuntimeInit.invokeStaticMain()静态方法调用"com.android.server.SystemServer"的main方法。

SystemServer.main

传递调用native方法init1():

class SystemServer {
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
}

init1()的工作:

注册Service Manager的死亡通知:调用binderDied()。System进程执行kill结束自己。

创建SurfaceFlinger、和SensorService两个服务。

返回SystemServer.init2()继续启动java语言开发的系统服务。

SystemServer.init2

public static final void init2() {
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}

ServerThread继承自Thread。

ServerThread.run

class ServerThread extends Thread {
@Override
public void run() {
Looper.prepare();
...
// Critical services...
try {
...
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
...
Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);
...
Slog.i(TAG, "Content Manager");
ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
...
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
((ActivityManagerService)ServiceManager.getService("activity"))
.setWindowManager(wm);
...
} catch (RuntimeException e) {
Slog.e("System", "Failure starting core service", e);
}
...
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
}

启动各个Service然后注册到ServiceManager。

各个服务都使用Binder和其它服务使用者进程进行就行交互。

(本文使用Atom编写)

笔记:Zygote和SystemServer进程启动过程的更多相关文章

  1. Android系统启动流程(三)解析SystemServer进程启动过程

    1.Zygote启动SystemServer进程 在上一篇文章中我们讲到在ZygoteInit.java的startSystemServer函数中启动了SyetemServer进程,如下所示. fra ...

  2. Zygote及System进程启动

    1.  init 根据init.rc 运行 app_process, 并携带‘--zygote' 和 ’--startSystemServer' 参数. 2.  AndroidRuntime.cpp: ...

  3. Android应用程序进程启动过程(前篇)

    在此前我讲过Android系统的启动流程,系统启动后,我们就比较关心应用程序是如何启动的,这一篇我们来一起学习Android7.0 应用程序进程启动过程,需要注意的是“应用程序进程启动过程”,而不是应 ...

  4. Android应用程序进程启动过程的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址: http://blog.csdn.net/luoshengyang/article/details/6747696 Android 应用程序框架层创 ...

  5. Android应用程序进程启动过程(后篇)

    前言 在前篇中我们讲到了Android应用程序进程启动过程,这一篇我们来讲遗留的知识点:在应用程序进程创建过程中会启动Binder线程池以及在应用程序进程启动后会创建消息循环. 1.Binder线程池 ...

  6. Android系统启动流程(二)解析Zygote进程启动过程

    1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器.它通过 ...

  7. Android系统启动流程(一)解析init进程启动过程

    整体流程大致如下:     1.init简介 init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等.in ...

  8. Linux进程启动过程简析

    朱宇轲 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 今天,我们将通过 ...

  9. Android(java)学习笔记161:Framework运行环境之启动SystemServer进程

          SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的.与启动普通进程的差别 ...

随机推荐

  1. python 打开浏览器的方法 Python打开默认浏览器

    一.python 打开浏览器的方法: . startfile方法(打开指定浏览器) import os os.startfile("C:\Program Files\internet exp ...

  2. python zlib ,zlib 压缩流

    zlib 字符串:使用zlib.compress可以压缩字符串.使用zlib.decompress可以解压字符串. 数据流:压缩:compressobj,解压:decompressobj       ...

  3. java redispool测试类保存

    这两天睡眠不足,今晚吃完饭,肚子烦躁的很,迟迟进入不了代码的状态,强打精神,又赶上处理了几个编辑器的报错,等到真正面对问题的时候又是晚上十一点, 晚上十一点是幸运点,到这个点无关问题都能解决完毕进入调 ...

  4. Spring的xml配置文件中约束的必要性 找不到元素 'beans' 的声明

    今天在复习Spring MVC框架的时候,只知道xml配置文件中的约束有规范书写格式的作用,所以在配置HandlerMapping对象信息的时候没有加入约束信息之后进行测试,没有遇到问题.后来在配置S ...

  5. mac 删除文件不经过废纸篓解决办法

    mac 删除文件不经过废纸篓,提示“此项目将被立刻删除,您不能撤销此操作.”,解决办法. 终端机运行两个命令: rm -R ~/.Trash killall Finder 退出终端机. ------- ...

  6. Hishop数据库根据产品ProductID取产品规格

    #region 产品规格 public static string GetSku(int ProductId) { DataTable skus =GetSkus(ProductId); // Res ...

  7. Python json.dumps 自定义序列化操作

    def login_ajax(request): if request.method == "GET": return render(request, 'login_ajax.ht ...

  8. 深入理解JVM(七)JVM类加载机制

    7.1JVM类加载机制 虚拟机把数据从Class文件加载到内存,并且校验.转换解析和初始化最终形成可以被虚拟机使用的Java类型,这就是虚拟机的类加载机制. 7.2类加载的时机 1.类加载的步骤开始的 ...

  9. WebDriver中的操作使用

    1.WebDriver中使用jquery假如设定jquery包的路径为path,则程序如下: String jquery=null; FileInputStream input = new FileI ...

  10. svn2个小问题的解决

    Revision file (r615) lacks trailing newline /svndata/your_project/db/revs /svndata/your_project/db/r ...