Android 作業系統開機時,會經由 init.rc 來啟動許多外部程式,其中有一個最重要 process 稱為 Zygote。Zygote 是 Android 的 monitor process,它主要負責二項工作:
1. 啟動 system server
2. 執行 Android 應用程式
「System Server」是由 Zygote 所建立的另外一個 process,建立 system server 的方式是使用典型的 Linux system call - fork()。當 Zygote 成功建立 system server 後,便進入 socket listening 模式。在此模式下,zygote 會監聽(listen)由 socket 所傳入的「命令」,並依據命令的內容啟動 Android 應用程式。
Zygote 啟動外部 Android 應用程式的方式,同樣是使用 Linux kernel 所提供的 fork() system call。因此,在 socket 做 listening,並依據命令來 fork() 並執行外部 Android 應用程式,稱之為「Zygote Mode」。
android的系统应用中的一个重要的进程就是zygote,所有的java应用程序进程都是由zygote派生出来的,zygote这个进程的作用就是“生儿子”。具体的一个应用如何出来的大家可以看我以前的一篇文章-----Android 应用初始化及窗体事件的分发。
首先要了解一点初始化语言的基本知识吧:
Services(服务)是一个程序,他在初始化时启动,并在退出时重启(可选)。Services(服务)的形式如下:
service <name> <pathname> [ <argument> ]*
<option>
<option>
Options为选项,具体可以参考linux service命令
zygote进程正是在linux kernel startup后通过这个文件启动的,具体看init.rc中这一段:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
一段一段的分析这个代码:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
启动服务名字zygote. /system/bin/app_process 进程的bin文件具体路径,后面跟的就是启动参数-Xzygote /system/bin --zygote --start-system-server。这段参数有什么作用可以对照看代码app_main.cpp
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;LOGV("App process is starting with pid=%d, class=%s./n",
getpid(), runtime.getClassName());
runtime.start();
}
}-Xzygote 这个参数的意义是在jvm中设置gDvm.zygote = true;至于这个参数的具体作用大家自己看代码吧。 其流程是 androidRuntime->start() call---> JNI_CreateJavaVM() call ---->dvmStartup()(戴维林虚拟机初始化) call---->dvmProcessOptions().
/system/bin :也许是告知系统应用的路径吧,大家看到了告诉我。
onrestart write /sys/android_power/request_state wake:
如果这个服务重启了,打开/sys/android_power/request_state 这个文件写入wake字符串。
Zygote Service
在本章我们会接触到这两个单词:
•Zygote [生物] 受精卵, 接合子, 接合体
•Spawn:产卵
通过这两个单词,我们就可以大体知道Zygote是干什么的了,就是叫老母鸡下蛋。通过“Zygote”产出不同的子“Zygote”。从大的架构上讲,Zygote是一个简单的典型C/S结构。其他进程作为一个客服端向Zygote发出”孵化”请求,Zygote接收到命令就“孵化”出一个Activity进程来。
Zygote系统代码组成及其调用结构:
•Zygote.java
提供访问Dalvik “zygote”的接口。主要是包装Linux系统的Fork,以建立一个新的VM实例进程。
•ZygoteConnection.java
Zygote的套接口连接管理及其参数解析。其他Actvitiy建立进程请求是通过套接口发送命令参数给Zygote。
•ZygoteInit.java
Zygote的main函数入口。Zygote系统代码层次调用
main()Startsystemserver()…
RunSelectLoopMode()
Accept socket connection
Conntecion.RunOnce()
Read argument
folkAndSpecialize
folkAndSpecialize使用Native函数Dalvik_dalvik_system_Zygote_forkAndSpecialize
//native 的获取
dalvik/vm/native
//dalvik_system_Zygote.cconst DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
{ "fork", "()I",
Dalvik_dalvik_system_Zygote_fork },
{ "forkAndSpecialize", "(II[II[[I)I",
Dalvik_dalvik_system_Zygote_forkAndSpecialize },
{ "forkSystemServer", "(II[II[[I)I",
Dalvik_dalvik_system_Zygote_forkSystemServer },
{ NULL, NULL, NULL },
};
在这里我们就有了Zygote服务的全貌理解,也在Code中印证了,Activity在本质上是个什么东西,就是一个Linux进程。但是不是一个简单的Linux进程,毕竟Activity是在Andoid概念空间中才有效的。在这个概念空间中,Activity被包装,在屏幕上呈现UI,用户看到的整个屏幕或者一个窗口,对于机器来讲,呈现在用户面前的就叫Actvitiy。从分析中我们可以看到,Android使用了Linux的fork机制。在Linux中Fork是很高效的。
一个Android的Activity实际上一个Linux进程,所谓进程具备下面几个要素,
a.要有一段程序供该进程运行,程序是可以被多个进程共享的。b..进程专用的系统堆栈空间。
c.进程控制块,在linux中具体实现是task_struct
d.有独立的存储空间。fork 创造的子进程复制了父亲进程的资源,包括内存的内容task_struct内容,在复制过程中,子进程复制了父进程的task_struct,系统堆栈空间和页面表,而当子进程改变了父进程的变量时候,会通过copy_on_write的手段为所涉及的页面建立一个新的副本。所以只有子进程有改变变量时,子进程才新建了一个页面复制原来页面的内容,基本资源的复制是必须的,整体看上去就像是父进程的独立存储空间也复制了一遍。
再看看下面Google在讲解Dalvik虚拟机的图片,我们就大体有了Android系统中Actvitiy的实际映射状态有了基本的认识。
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/maxleng/archive/2010/04/20/5508488.aspx