init进程通过解析init.zygote.rc文件fork出zygote进程,然后会执行app_main.cpp的main方法, 这个函数有两种启动模式:
- 一种是zygote模式,也就是初始化zygote进程,传递的参数有--start-system-server --socket�name=zygote,前者表示启动SystemServer,后者指定socket的名称
- 一种是application模式,也就是启动普通应用程序,传递的参数有class名字以及class带的参数
两者最终都是调用AppRuntime对象的start函数,加载ZygoteInit或RuntimeInit两个Java类,并将之前整理的参数传入进去
// \frameworks\base\cmds\app_process\app_main.cpp main()
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
}
if (zygote) {
//这些Java的应用都是通过 AppRuntime.start(className)开始的
//其实AppRuntime是AndroidRuntime的子类,它主要实现了几个回调函数,
//而start()方 法是实现在AndroidRuntime这个方法类里
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
app_process 里面定义了三种应用程序类型:
- Zygote: com.android.internal.os.ZygoteInit
- System Server, 不单独启动,而是由Zygote启动
- 其他指定类名的Java 程序
上面的runtime 指的AppRuntime, AppRuntime继承AndroidRuntime,所以我们来看看AndroidRuntime 的 start方法
// \frameworks\base\core\jni\androidRuntime.cpp start() L1091
void AndroidRuntime::start(const char* className,
const Vector<String8>& options, bool zygote) {
...
JNIEnv* env;
//JNI_CreateJavaVM L1015
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
}
startVm()方法主要是创建java 虚拟机
Java虚拟机的启动大致做了以下一些事情:
1. 从property读取一系列启动参数。
2. 创建和初始化结构体全局对象(每个进程)gDVM
,及对应与JavaVM和JNIEnv的内部结构体JavaVMExt, JNIEnvExt.
3. 初始化java虚拟机,并创建虚拟机线程
4. 注册系统的JNI,Java程序通过这些JNI接口来访问底层的资源。
5. 为Zygote的启动做最后的准备,包括设置SID/UID, 以及mount 文件系统
6. 返回JavaVM 给Native代码,这样它就可以向上访问Java的接口
除了系统的JNI接口(”javacore”, “nativehelper”), android framework 还有大量的Native实现,
Android将所有这些接口一次性的通过startReg()来完成
上述代码执行完后,会通过反制执行到java端的ZygotInit.java 的main()方法
public static void main(String argv[]) {
//新建Zygote服务器端
//1 重点
ZygoteServer zygoteServer = new ZygoteServer();
...
final Runnable caller;
try {
...
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
//还记得app_main.cpp中传的start-system-server参数吗,在这里总有用 到了
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = 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]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
//注册Socket
//2 重点
zygoteServer.registerServerSocketFromEnv(socketName);
// 在有些情况下我们需要在第一个fork之前进行预加载资源
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//3 重点
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
//主动进行一次资源GC
//4 重点
gcAndFinalize();
bootTimingsTraceLog.traceEnd();
bootTimingsTraceLog.traceEnd();
Trace.setTracingEnabled(false, 0);
Zygote.nativeSecurityInit();
Zygote.nativeUnmountStorageOnInit();
ZygoteHooks.stopZygoteNoThreadCreation();
//5 重点
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
//6 重点
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
//7 重点
zygoteServer.closeServerSocket();
}
if (caller != null) {
//8 重点
caller.run();
}
}
首先总结一下main()主要做的事情,然后再具体分析上面的8个重点
1.注册一个name为zygote 的socket,用来与其他进程通信,
这里的其他进程主要指systemserver进程,
用来接收AMS发送的socket消息,fork出用户app进程
2.预加载安卓系统资源。
3.fork systemserver 进程
4.循环从socket里面取消息
重点1和2 :新建Zygote服务器端,注册Socket
重点3 : preload(bootTimingsTraceLog);
preload() 的作用就是提前将需要的资源加载到VM中,比如class、resource等
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
beginIcuCachePinning();
bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
bootTimingsTraceLog.traceBegin("PreloadClasses");
//加载指定的类到内存并且初始化,使用的Class.forName(class, true, null);方式
preloadClasses();
bootTimingsTraceLog.traceEnd(); // PreloadClasses
bootTimingsTraceLog.traceBegin("PreloadResources");
//加载Android通用的资源,比如drawable、color...
preloadResources();
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
nativePreloadAppProcessHALs();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
//加载OpenGL...
preloadOpenGL();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
//加载共用的Library
preloadSharedLibraries();
//加载Text资源,字体等
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
// 为了内存共享,WebViewFactory进行任何初始化都要在Zygote进程中
WebViewFactory.prepareWebViewInZygote();
endIcuCachePinning();
warmUpJcaProviders();
Log.d(TAG, "end preload");
sPreloadComplete = true;
}
preloadClassess 将framework.jar里的preloaded-classes 定义的所有class load到内存里,preloaded-classes 编译Android后可以在framework/base下找到。
而preloadResources 将系统的Resource(不是在用户apk里定义的resource)load到内存。资源preload到Zygoted的进程地址空间,所有fork的子进程将共享这份空间而无需重新load, 这大大减少了应用程序的启动时间,但反过来增加了系统的启动时间。通过对preload 类和资源数目进行调整可以加快系统启动。Preload也是Android启动最耗时的部分之一
重点4 gcAndFinalize()
static void gcAndFinalize() {
final VMRuntime runtime = VMRuntime.getRuntime();
/* runFinalizationSync() lets finalizers be called in Zygote,
* which doesn't have a HeapWorker thread.
*/
System.gc();
runtime.runFinalizationSync();
System.gc();
}
gc()调用只是通知VM进行垃圾回收,是否回收,什么时候回收全由VM内部算法决定。GC的回收有一个
复杂的状态机控制,通过多次调用,可以使得尽可能多的资源得到回收。gc()必须在fork之前完成(接下
来的StartSystemServer就会有fork操作),这样将来被复制出来的子进程才能有尽可能少的垃圾内存没
有释放
重点5 forkSystemServer
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
/* Request to fork the system server process */
//fork出SystemServer进程,返回pid,这里的pid为0, 后续代码运行在SystemServer进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//下面代码运行在SystemServer进程
//fork会将父进程的主线程的一切都复制过来
// Socket 也复制过来了,SystemServer进程进程间通信使用binder,
// 所以关掉Socket
zygoteServer.closeServerSocket();
//处理SystemServer进程
return handleSystemServerProcess(parsedArgs);
}
return null;
}
handleSystemServerProcess()用来处理SystemServer进程
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
····
if (parsedArgs.invokeWith != null) {
····
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
// 为systemServer创建了一个类加载器PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
接下来分析ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl)
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
//1
ZygoteInit.nativeZygoteInit();
//2
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
接下来分析上面的1,2处
ZygoteInit.nativeZygoteInit()方法是一个本地方法,会调用到 natvie层,在AndroidRuntime.cpp类中可以查看到nativeZygoteInit()方法对应的native函数:
/*
* JNI registration.
*/
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
从上面可以看出nativeZygoteInit对应的native方面为com_android_internal_os_ZygoteInit_nativeZygoteInit
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime指向AppRuntime,所以我们来看AppRuntime的onZygoteInit()方法
virtual void onZygoteInit()
{
// 创建ProcessState对象,用来打开Binder 驱动,创建Binder线程池,让其进程里面的所有线程都能通过Binder通信
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
// 启动Binder线程池,最终会调用到
//IPCThreadState实例的joinThreadPool()函数,
//进行Binder线程池相关的处理
proc->startThreadPool();
}
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader)
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
//findStaticMain来运行args的startClass的main方法
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
findStaticMain从名字就可以看出来,是用来寻找方法名为main()的静态方法,我们这里寻找到的其实是SystemServer.Java的main()方法,通过参数确定的
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//通过反射获取到class对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
...
}
Method m;
try {
//通过反射获取到main()方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
...
} catch (SecurityException ex) {
...
}
...
return new MethodAndArgsCaller(m, argv);
}
返回 new MethodAndArgsCaller(m, argv) 对象,继承自 Runnable
static class MethodAndArgsCaller 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是SystemServer.Java的main() 方法
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);
}
}
}
MethodAndArgsCaller最终会返回到重点5的r对象,r就是MethodAndArgsCaller
所以r.run()会调用到MethodAndArgsCaller的run()方法,
里面会调用到SystemServer.main(),启动SystemServer进程,SystemServer进程的分析请看下一篇文章。
重点6循环socket,从里面获取到fork 用户进来的消息,fork出app进程
Runnable runSelectLoop(String abiList) {
...
while (true) {
...
ZygoteConnection connection = peers.get(i);
...
final Runnable command = connection.processOneCommand(this);
....
if (mIsForkChild) {
return command;
}
...
}
...
}
//分析这个connection.processOneCommand(this)
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
//fork出孩子进程,返回pid=0
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
//
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//处理孩子进程
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
...
}
} finally {
...
}
}
在分析 handleChildProc方法
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
....
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
...
}
从上面可以看出来,接下来的过程和SystemServer一样,会返回到重点8
执行run()方法,这里的run 方法会执行ActivityThreed的main()方法,这是我们用户app的入口。