1 综述
Android系统存在两个不同的世界:
- Java世界,主要是Android的SDK,运行基于
ART/Dalvik
虚拟的Java程序 - Native世界,
c/c++
开发的程序
2 Zygote分析
Zygote
本身是一个Native
的应用程序,和驱动、内核等均无关系。Zygote
是由init
进程根据init.rc
的配置而创建的。根据上一章知道init
进程通过fork/execve
执行了zygote
配置的可执行文件/system/bin/app_process
,其对应的文件是frameworks/base/cmds/app_process/App_main.cpp
int main(int argc, char* const argv[]){
...//省略
if (zygote) {
//由AndroidRuntime来完成start
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else
... //省略
}
main
函数比较简单,创建 AppRuntime
对象。设置一些参数,设置进程名称等,主要操作还在集中在runtime.start(...)
函数中。
AppRuntime
继承了AndroidRuntime
重载了onVmCreated()
,onStarted()
,onZygoteInit()
,onExit()
四个函数。main
中调用的函数start()
在AndroidRuntime
中实现
2.1 AppRuntime分析
framework/base/core/jni/AnroidRuntime.cpp
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
//className的值是"com.android.internal.os.ZygoteInit"
...//省略
//如果环境变量中没有ANDROID_ROOT,则新增该变量,并设置值为“/system"
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
... }
setenv("ANDROID_ROOT", rootDir, 1);
}
/* start the virtual machine */
//创建虚拟机
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/* Register android functions.*/
//注册JNI函数
if (startReg(env) < 0) {...//错误,退出}
/*
* 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);//创建String[]
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className); //把nativeString变成JString
assert(classNameStr != NULL);
//把className放在数据的0位置
env->SetObjectArrayElement(strArray, 0, classNameStr);
//把options中的数据放入数组中
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.
*/
//把 '.'替换为'/',在native中'.'有特殊含义
char* slashClassName = toSlashClassName(className);
//拿到com.android.internal.os.ZygoteInit的class对象
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
...
} else {
//获取 main函数的jmeothodID对象
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
if (startMeth == NULL) {...}
else {
//执行main函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...//省略,异常检测
}
}
free(slashClassName);
//Zygote退出,在正常情况下,Zygote不需要退出。
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(...)
可知,其中有三个关键点:
- 创建VM,重点代码
AndroidRuntime::startVm(...)
- 注册JNI函数,重点代码
AndroidRuntime::startReg(env)
- 进入Java世界
2.1.1 创建虚拟机-startVm
framewors/base/core/jni/AnroidRuntime.cpp
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
....//一大片设置vm参数代码
/*
* The default starting and maximum size of the heap. Larger
* values should be specified in a product property override.
*/
//只有看到这个最亲切了 - ^ -
parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
...//一大片设置参数代码
/*
* Initialize the VM.
*
* The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
* If this call succeeds, the VM is ready, and we can start issuing
* JNI calls.
*/
// 调用JNI_CreateJavaVM创建虚拟机,pEnv返回当前线程的JNIEnv变量
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
... }
return 0;
}
2.1.2 注册JNI函数-startReg
给虚拟机注册一些JNI函数,因为Java世界中需要调用一些native方式实现的函数。
frameworks/base/core/jni/AnroidRuntime.cpp
int AndroidRuntime::startReg(JNIEnv* env){
ATRACE_NAME("RegisterAndroidNatives");
/*
* This hook causes all future threads created in this process to be
* attached to the JavaVM. (This needs to go away in favor of JNI
* Attach calls.)
*/
//设置Thread类的线程创建函数为javaCreateThreadEtc (第五章详解)
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
/*
* Every "register" function calls one or more things that return
* a local reference (e.g. FindClass). Because we haven't really
* started the VM yet, they're all getting stored in the base frame
* and never released. Use Push/Pop to manage the storage.
*/
env->PushLocalFrame(200);
//注册jni函数,gRegJNI是一个全局数组。
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
...}
env->PopLocalFrame(NULL);
return 0;
}
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
//调用数组元素的mProc函数
if (array[i].mProc(env) < 0) {
... }
}
return 0;
}
//保存的是一个函数
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_android_os_SystemClock),
...
}
//JNI注册函数对应的结构体
#define REG_JNI(name) { name, #name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
const char* mName;
};
在register_jni_procs()
中调用每项的mProc(...)
函数,实际实行的就是每项的的函数指针,进行对应当中的JNI函数注册,例:
frameworks/base/core/jni/AnroidRuntime.cpp
int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
{
return jniRegisterNativeMethods(env,
"com/android/internal/os/RuntimeInit",gMethods, NELEM(gMethods));
}
2.2 进入Java世界
vm已经创建好了,JNI函数也注册好了,接下来就是执行CallStaticVoidMethod(...)
调用执行com.android.internal.os.ZygoteInit::main(...)
函数了
frameworks/base/core/java/com/android/internal/os/Zygote.java
public static void main(String argv[]) {
//创建ZygoteServer,一些Zygote的socket操作已经放到了ZygoteServer中
ZygoteServer zygoteServer = new ZygoteServer();
/** 没理解 - start **/
// Mark zygote start. This ensures that thread creation will throw an error.
//???通知vm?
ZygoteHooks.startZygoteNoThreadCreation();
/** 没理解 - end **/
// Zygote goes into its own process group.
try {
//设置groupID,好像之前的版本都没有这个设置
Os.setpgid(0, 0);
} catch (ErrnoException ex) {...}
}
try {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
RuntimeInit.enableDdms();//开启DDMS功能
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
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]);
}
}
...//省略
//为Zygote注册sokect
zygoteServer.registerServerSocket(socketName);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(); //预加载类和资源
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
gcAndFinalize();//强制GC一次
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// Disable tracing so that forked processes do not inherit stale tracing tags from Zygote.
Trace.setTracingEnabled(false);
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
ZygoteHooks.stopZygoteNoThreadCreation();
//启动system_server
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
//进入循环,等待socket消息
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run(); //重要
} catch (RuntimeException ex) {
zygoteServer.closeServerSocket();
throw ex;
}
2.2.1 创建Zygotes socket
Zygote
采用socket
的方式接收请求,关于Zygote
的socket
操作全部封装到了ZygoteServer.java
中
frameworks/base/core/java/com/android/internal/os/Zygote.java
/**
* Registers a server socket for zygote command connections
*/
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) { ..}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc); //设置文件描述符
//创建Socket的本地服务端
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {...}
}
}
2.2.2 预加载类和资源
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload() {
...//Trace
beginIcuCachePinning();
...//Trace
//预加载位于framework/base/preload-classes文件中的类
preloadClasses();
...//Trace
//预加载资源,包含drawable和color等资源
preloadResources();
...//Trace
//预加载OpenGL
preloadOpenGL();
...//Trace
//通过System.loadLibrary()方法,
//预加载"android","compiler_rt","jnigraphics"这3个共享库
preloadSharedLibraries();
//预加载文本连接符资源
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
//仅用于zygote进程,用于内存共享的进程
WebViewFactory.prepareWebViewInZygote();
endIcuCachePinning();
warmUpJcaProviders();
}
加载class时采用的Class.forName(...)
//[frameworks/base/core/java/com/android/internal/os/ZygoteInit.java::preloadClasses]
// Load and explicitly initialize the given class. Use
// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
// (to derive the caller's class-loader). Use true to force initialization, and
// null for the boot classpath class-loader (could as well cache the
// class-loader of this class in a variable).
Class.forName(line, true, null);
说明:preload_class文件由framework/base/tools/preload工具生成,它需要判断每个类加载的时间是否大于1250微秒,超过这个时间的类就会被写到preload-classes文件中,最后由zygote预加载。
这个参数可以在frameworks/base/tools/preload/WritePreloadedClassFile.java
中找到
/**
* Preload any class that take longer to load than MIN_LOAD_TIME_MICROS us.
*/
static final int MIN_LOAD_TIME_MICROS = 1250;
2.2.3 总结
Zygote的分析整体和原书保持一致,按照原书的流程看源码,基本是一致的。更加面向对象的封装让源码看起更加清晰。
- 创建AppRuntime对象,并调用它的start。此后的活动则由AppRuntime来控制。
- 调用startVm创建Java虚拟机,然后调用startReg来注册JNI函数。
- 通过JNI调用com.android.internal.os.ZygoteInit类的main函数,从此进入了Java世界。然而在这
个世界刚开创的时候,什么东西都没有。 - 调用registerZygoteSocket。通过这个函数,它可以响应子孙后代的请求。同时Zygote调用preload(),为Java世界添砖加瓦。
- Zygote觉得自己工作压力太大,便通过调用startSystemServer分裂一个子进程system_server来为Java世界服务。
- Zygote完成了Java世界的初创工作,它已经很满足了。下一步该做的就是调用runSelectLoopMode后,便沉沉地睡去了。
3 SystemService
Zygote
还有一个重要的作用,启动SystemServer
//启动system_server
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
3.1 SystemServer的诞生
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
...//省略
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 {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
//调用forSystemServerfork一个新的进程
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 */
//systemserver进程中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
handleSystemServerProcess(parsedArgs);
}
return true;
}
上面代码调用了Zygote.forkSystemServer(...)
去for新进程,进入继续查看
frameworks/base/core/java/com/android/internal/os/Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
//继续调用函数fork
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
继续调用一个native
函数实现fork,nativeForkSystemServer(...)
对应的JNI实现为com_android_internal_os_Zygote_nativeForkSystemServer(...)
,文件位置:
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
//继续调用函数fork进程
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
if (pid > 0) {
// The zygote process checks whether the child process has died or not.
// zygote进程中,检测system_server进程是否创建
gSystemServerPid = pid;
// There is a slight window that the system server process has crashed
// but it went unnoticed because we haven't published its pid yet. So
// we recheck here just to make sure that all is well.
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
//当system_server进程死亡后,重启zygote进程
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}
// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
//设置信号处理
SetSigChldHandler();
...//省略
// fork进程
pid_t pid = fork();
if (pid == 0) {
//子进程
//关闭并清除文件描述符
DetachDescriptors(env, fdsToClose);
if (!is_system_server) {
//对于非system_server子进程,则创建进程组
int rc = createProcessGroup(uid, getpid());
...
}
//设置gid
SetGids(env, javaGids);
//设置资源limits
SetRLimits(env, javaRlimits);
...//省略
}
...//省略}
继续查看SetSigChldHandler()
函数
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler;
//设置处理信号。该信号是子进程死亡的信号
int err = sigaction(SIGCHLD, &sa, NULL);
...//省略
}
信号的处理函数是SigChldHandler(...)
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
// It's necessary to save and restore the errno during this function.
// Since errno is stored per thread, changing it here modifies the errno
// on the thread on which this signal handler executes. If a signal occurs
// between a call and an errno check, it's possible to get the errno set
// here.
// See b/23572286 for extra information.
int saved_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Log process-death status that we care about. In general it is
// not safe to call LOG(...) from a signal handler because of
// possible reentrancy. However, we know a priori that the
// current implementation of LOG() is safe to call from a SIGCHLD
// handler in the zygote process. If the LOG() implementation
// changes its locking strategy or its use of syscalls within the
// lazy-init critical section, its use here may become unsafe.
if (WIFEXITED(status)) {
if (WEXITSTATUS(status)) {
ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
}
} else if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGKILL) {
ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
}
if (WCOREDUMP(status)) {
ALOGI("Process %d dumped core.", pid);
}
}
// If the just-crashed process is the system_server, bring down zygote
// so that it is restarted by init and system server will be restarted from there.
//如果死去的子进程是SS,则Zygote把自己也干掉了,Zygote死掉会导致init重启zygote,这样zygote又能启动systemserver
if (pid == gSystemServerPid) {
...
kill(getpid(), SIGKILL);
}
}
// Note that we shouldn't consider ECHILD an error because
// the secondary zygote might have no children left to wait for.
if (pid < 0 && errno != ECHILD) {...}
errno = saved_errno;
}
由上面代码可知,做为Zygote
的嫡长子,system_server
确实具有非常高的地位,竟然到了与Zygote生死与共的地步!
3.2 SystemServer的重要使命
fork
出system_server
代码执行回到startSystemServer(...)
(frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
)中
//[startSystemServer(...)代码片段]
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
//?两个zygote进程(zygote/zygote64)?之后去了解先写笔记
waitForSecondaryZygote(socketName);
}
//关闭从Zygote那里继承下来的Socket
//因为fork()创建新进程,采用copy on write方式
//子进程继承了父进程的所所有资源?是这么理解吧?
zygoteServer.closeServerSocket();
//开启system_server的使命
handleSystemServerProcess(parsedArgs);
}
开启使命:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
// 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) {
// 执行dex优化操作
performSystemServerDexOpt(systemServerClasspath);
}
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
//调用ZygoteInit函数。
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
其中systemServerClasspath
环境变量主要有/system/framework/
目录下的services.jar
,ethernet-service.jar
, wifi-service.jar
这3个文件。
根据代码执行,继续跟入RuntimeInit.zygoteInit(...)
函数
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader)throws Zygote.MethodAndArgsCaller {
...//省略
//做一些常规初始化
commonInit();
//native层的初始化
nativeZygoteInit();
//应用初始化
applicationInit(targetSdkVersion, argv, classLoader);
}
zygoteInit(...)
主要执行了三个函数调用完成。
private static final void commonInit() {
/*
* set handlers; these apply to all threads in the VM. Apps can replace
* the default handler, but not the pre handler.
*/
// 设置默认的未捕捉异常处理方法
Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());
/*
* Install a TimezoneGetter subclass for ZoneInfo.db
*/
// 设置时区,中国时区为"Asia/Shanghai"
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);
//重置log配置
LogManager.getLogManager().reset();
new AndroidConfig();
/*
* Sets the default HTTP User-Agent used by HttpURLConnection.
*/
// 设置默认的HTTP User-agent格式,用于 HttpURLConnection
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
/*
* Wire socket tagging to traffic stats.
*/
NetworkManagementSocketTagger.install();
...//
}
3.2.1 zygoteInitNative分析
非常重要的函数,单独列在一个小节里面。这是一个native
函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_RuntimeInit_nativeZygoteInit
(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime
是AndroidRuntime.cpp
中的一个全局静态变量
static AndroidRuntime* gCurRuntime = NULL;
在app_process.cpp
中的main
首先就构造了一个AppRuntime
对象
int main(int argc, char* const argv[]){
...//省略
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...//省略
}
在本章开篇就说了AppRuntime
继承自AndroidRuntime
,在构造AppRuntime
会先构造AndroidRuntime
,查看AndroidRuntime
的构造函数,果然就这这里赋值了:
AndroidRuntime::AndroidRuntime(...):...{
...//
assert(gCurRuntime == NULL); // one per process
gCurRuntime = this;
}
找到了真身,继续分析onZygoteInit()
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
////启动一个线程,用于Binder通信。
proc->startThreadPool();
}
ProcessState::self()
是单例模式,主要工作是调用open()
打开/dev/binder
驱动设备,再利用mmap()映射内核的地址空间,将Binder
驱动的fd
赋值ProcessState
对象中的变量mDriverFD
,用于交互操作。稍后的章节中会详解
3.2.2 applicationInit(…)
zygoteInit(...)
第三个重要函数:
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
//true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
nativeSetExitWithoutCleanup(true);
//设置虚拟机的内存利用率参数值为0.75
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
...//
// Remaining arguments are passed to the start class's static main
//调用startClass的static方法 main()
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
这里的startClass
的参数就是com.android.server.SystemServer
,做了那么多准备,终于看到要执行main函数了
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {...}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
...} catch (SecurityException ex) {
...}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {...}
/*
* 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 Zygote.MethodAndArgsCaller(m, argv);
}
由于system_server
是从zygote``fork
出来的,所以拥有相同的含函数栈,只是运行在两个不同进程,互不干扰(不知道这种说法对不对…求指教)。所以,这里抛出异常,就会沿着当前的进程的函数栈w往上抛,直到遇到catch
,沿着调用栈找到
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
//main函数
try{...} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
}
现在函数执行到这里,对于zygote
进程来说,因为没有异常,继续后面的代码,而system_server
抛出了异常,进入异常处理代码:
frameworks/base/core/java/com/android/internal/os/Zygote.java::MethodAndArgsCaller::run()
public void run() {
try {
//这个mMethod为com.android.server.SystemServer的main函数
mMethod.invoke(null, new Object[] { mArgs });
}catch{...}
}
3.2.3 SystemServer的真面目
上面的代码明确的表示了SystemServer
的main
函数被调用
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
//创建SystemServer对象并调用对象的run()方法
new SystemServer().run();
}
private void run() {
...//
//如果时间当前时间小于1970设置为1970
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
...//
//变更虚拟机的库文件
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
...//
//清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间
VMRuntime.getRuntime().clearGrowthLimit();
//设置内存的可能有效使用率为0.8
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
...//
//访问环境变量前,需要明确地指定用户
Environment.setUserRequired(true);
// Within the system server, any incoming Bundles should be defused
// to avoid throwing BadParcelableException.
BaseBundle.setShouldDefuse(true);
// Ensure binder calls into the system always run at foreground priority.
//确保当前系统进程的binder调用,总是运行在前台优先级
BinderInternal.disableBackgroundScheduling(true);
// Increase the number of binder threads in system_server
BinderInternal.setMaxThreads(sMaxBinderThreads);
//进程优先级设置,和不可自动变为后台进程
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// Prepare the main looper thread (this thread).
//准备当前线程的looper
Looper.prepareMainLooper();
// Initialize native services.
//加载android_servers.so
//该库的源码就在frameworks/base/services/core/jni下
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
//检车上次是否关机失败,这个方法可能不会返回
performPendingShutdown();
// Initialize the system context.
//创建system context
createSystemContext();
// Create the system service manager.
//创建SystemServiceManager并添加到本地服务中
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...//
//启动各种服务
startBootstrapServices();//引导服务
startCoreServices();//核心服务
startOtherServices();//其他服务
...//
//loop
Looper.loop();
}
在SystemServer.run()
方法中有很多有趣的函数调用可以研究一下
3.2.3.1 performPendingShutdown()
private void performPendingShutdown() {
//从系统属性中拿到关机的action属性
final String shutdownAction = SystemProperties.get(
ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
if (shutdownAction != null && shutdownAction.length() > 0) {
//拿到actiong的第一个标识为
boolean reboot = (shutdownAction.charAt(0) == '1');
//标识位后面都是reason
final String reason;
if (shutdownAction.length() > 1) {
reason = shutdownAction.substring(1, shutdownAction.length());
} else {
reason = null;
}
...//检查确保不是reboot into recovery to apply update
//关机或者重启
ShutdownThread.rebootOrShutdown(null, reboot, reason);
}
}
这个函数也比较简单,获取系统属性中是否写入得有sys.shutdown.requested
这个属性,如果有就解析这个属性,判断是否要进行reboot or shutdwon
。
3.2.3.2 createSystemContext()
private void createSystemContext() {
//创建ActivityThread对象
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
//设置主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}
第一个 ActivityThread.systemMain()
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
//内存低的设备关闭硬件加速,因为会增加很多开销
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
//创建AcvityThread
ActivityThread thread = new ActivityThread();
//创建Application以及调用其onCreate()方法
thread.attach(true);
return thread;
}
3.2.4开启其他的服务
在SystemServer.run()
方法的里,也是SystemServer
最重要的任务,启动系统服务:startBootstrapServices()
,startCoreServices()
,startOtherServices()`
3.2.4.1 startBootstrapServices
private void startBootstrapServices() {
//确保installer服务先启动,在installer内部有LocalSocket,先mark,以后在分析
Installer installer = mSystemServiceManager.startService(Installer.class);
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Now that the power manager has been started, let the activity manager
// initialize power management features
//初始化activityManagerService的power management功能
mActivityManagerService.initPowerManagement();
//启动服务LightsService
mSystemServiceManager.startService(LightsService.class);
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// We need the default display before we can initialize the package manager.
//方法里面追个调用已经添加到serviceManager中service,通知它们当前阶段????先留着,因为还有很多phase
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
// Only run "core" apps if we're encrypting the device.
//获得系统属性,设备加密的状态,如果在加密只运行核心服务
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
mOnlyCore = true;
}
//启动服务PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
...//不知道在说什么,注释也不会翻译
// Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
// A/B artifacts after boot, before anything else might touch/need them.
// Note: this isn't needed during decryption (we don't have /data anyways).
if (!mOnlyCore) {...}
//启动服务UserManagerService
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
// Initialize attribute cache used to cache resources from packages.
AttributeCache.init(mSystemContext);
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
//传感器服务需要访问其他服务才能才能,所以最后开启
startSensorService();
}
来总结一下上面创建了哪些service
:Installer
,ActivityManagerService
,PowerManagerService
,LightsService
,DisplayManagerService
,PackageManagerService
,UserManagerService
,SensorService
。启动顺序也是有讲究的。
3.2.4.2 startCoreServices
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
//启动服务BatteryService,用于统计电池电量
mSystemServiceManager.startService(BatteryService.class);
// Tracks application usage stats.
//追踪应用使用状态
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
//启动服务WebViewUpdateService
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}
三个服务:BatteryService
,UsageStatsService
,WebViewUpdateService
.
3.2.4.3 startOtherServices()
启动其他的服务,非常多。
private void startOtherServices() {
//太多了,还是不写了
...
}
3.3 总结
System_server
真是是非常重要,他需要负责将启动service
,特别是它他抛出异常,然后通过catch
异常来执行SystemServer
的main函数,不知道我理解的对不对。
4 Zygote的分裂
在Zygote
fork
出system_server
后执行zygoteServer.runSelectLoop(...)
等待处理请求.
4.1 ActivityManagerService发送请求
ActivityManagerService
是由system_server
启动的,并且是在startBootStrapServices
中启动的,书中直接就给出了在ActivityManagerService:: startProcessLocked(...)
来发起请求。第一次看到肯定还是很懵的。熟悉了app启动流程就知道,创建一个新的app进程,层层调用,最终就会执行到这个函数。
参考:
Android应用程序启动过程源代码分析
frameworks/base/services/java/com/android/server/SystemServer.java
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...//仅梳理流程,具体代码不详细解析,因为我都还没弄懂...哈哈。
//请求创建进程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
...//省略
}
这里面的代码很多,这部分我觉得作者只是回应Zygote
的socket
的作用,重点不在分析ActivityManagerService
所以不去深究其它的,因为太广了。
上面的start(...)
最终会执行到:
frameworks/base/core/java/com/android/os/ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(...)
throws ZygoteStartFailedEx {
...//省略
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
openZygoteSocketIfNeeded(...)
就是打开socket
连接,zygoteSendArgsAndGetResult(...)
发送请求,并读取结果。
4.2 Zygote的响应
上面已经给Zygote发送的请求,处理的函数就是zygoteServer.runSelectLoop(...)
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
//不端的查询
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
//没有客户端连接
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
//获得新的连接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
//处理请求
boolean done = peers.get(i).runOnce(this);
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
那么可以看到,有请求来就会去执行runOnce(...)
这个函数:
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
boolean runOnce(ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller {
...//
//读取写入的参数
args = readArgumentList();
...//
//for进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, parsedArgs.debugFlags,
rlimits, parsedArgs.mountExternal,
parsedArgs.seInfo,
parsedArgs.niceName,
fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
if (pid == 0) {
// in child
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//处理子进程
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// should never get here, the child is expected to either
// throw Zygote.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
...//
}
//处理函数
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws Zygote.MethodAndArgsCaller {
...//省略
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
//进入这个分支
//很熟悉,貌似见过。
//对,是他是他就是他,在system_server启动的时候也是掉了这个,最后还抛了异常回到main函数
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
5 总结
Zygote
在Java世界是爸爸,其他的都是他fork出来的,包括非常重要system_server
,其次zygote
还要这响应创建应用的请求。system_server
也是不得了,是老大。Java世界的服务都得由他来启动。