Android系统启动——Zygote启动
Posted cao_null
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android系统启动——Zygote启动相关的知识,希望对你有一定的参考价值。
上一篇讲到了init启动Zygote的过程,这次分析Zygote
涉及类
/frameworks/base/cmds/app_process/android.mk
/frameworks/base/cmds/app_process/app_main.cpp
/frameworks/base/core/jni/AndroidRuntime.cpp
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
执行到启动app_process64,我们打开app_process/Android.mk
//frameworks/base/cmds/app_process/Android.mk
LOCAL_PATH:= $(call my-dir)
app_process_common_shared_libs := \\
libandroid_runtime \\
libbinder \\
libcutils \\
libdl \\
libhwbinder \\
liblog \\
libnativeloader \\
libutils \\
app_process_common_shared_libs += \\
libwilhelm \\
app_process_common_static_libs := \\
libsigchain \\
//源文件
app_process_src_files := \\
app_main.cpp \\
app_process_cflags := \\
-Wall -Werror -Wunused -Wunreachable-code
app_process_ldflags_32 := \\
-Wl,--version-script,art/sigchainlib/version-script32.txt -Wl,--export-dynamic
app_process_ldflags_64 := \\
-Wl,--version-script,art/sigchainlib/version-script64.txt -Wl,--export-dynamic
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= $(app_process_src_files)
LOCAL_LDFLAGS_32 := $(app_process_ldflags_32)
LOCAL_LDFLAGS_64 := $(app_process_ldflags_64)
LOCAL_SHARED_LIBRARIES := $(app_process_common_shared_libs)
LOCAL_WHOLE_STATIC_LIBRARIES := $(app_process_common_static_libs)
//32和64位都是同一个
LOCAL_MODULE:= app_process
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := app_process32
LOCAL_MODULE_STEM_64 := app_process64
LOCAL_CFLAGS += $(app_process_cflags)
include $(BUILD_EXECUTABLE)
...
接下来是app_main
//app_main.cpp
int main(int argc, char* const argv[])
{
...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
//忽略第一个参数,然后组装参数
// --zygote : 启动zygot模式
// --start-system-server : 启动 system server.
// --application : 启动application模式
// --nice-name : 进程的nice name.
...
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
//遍历参数设置状态
while (i < argc) {
const char* arg = argv[i++];
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;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {
// 非zygote模式,参数传给应用 application
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + i;
int argc_new = argc - i;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append("\\"");
restOfArgs.append(argv_new[k]);
restOfArgs.append("\\" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else {
//这是 zygote 模式.
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");//制定abi
abiFlag.append(prop);
args.add(abiFlag);
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {//替换名字
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {
//启动zygote
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
//启动RuntimeInit
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
最终执行的是runtime.start
//app_main.cpp
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength)
: AndroidRuntime(argBlockStart, argBlockLength)
, mClass(NULL)
{
}
...省略其他方法,没有复写start
}
执行的是父类的start
//frameworks/base/core/jni/AndroidRuntime.cpp
//构造
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
//初始化skia
SkGraphics::Init();
// There is also a global font cache, but its budget is specified by
// SK_DEFAULT_FONT_CACHE_COUNT_LIMIT and SK_DEFAULT_FONT_CACHE_LIMIT.
// Pre-allocate enough space to hold a fair number of options.
mOptions.setCapacity(20);
assert(gCurRuntime == NULL); // one per process
gCurRuntime = this;
}
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
/* 启动虚拟机 */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//启动
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
//虚拟机创建完后的回调
onVmCreated(env);
/*
* 注册jni方法
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\\n");
return;
}
...
//替换路径找到ZygoteInit类
/*
* 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) {
ALOGE("JavaVM unable to locate class '%s'\\n", slashClassName);
/* keep going */
} else {
//找到main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\\n", className);
/* keep going */
} else {
//执行main
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
//释放资源
free(slashClassName);
...
}
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
...设置参数等
//启动JVM虚拟机
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\\n");
return -1;
}
return 0;
}
在这里做了关键的三步操作:
1.创建虚拟机
2.注册jni方法
3.调用main方法
最终执行java代码ZygoteInit类的main方法
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
//注册Socket
zygoteServer.registerServerSocket(socketName);
//有时候不需要预加载
// 第一次fork需要预加载
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
...
//启动SystemServer
if (startSystemServer) {
//最终调用nativeForkSystemServer,在native层启动SystemServer,不展开了
startSystemServer(abiList, socketName, zygoteServer);
}
//开始监听孵化请求
Log.i(TAG, "Accepting command socket connections");
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
startSystemServer负责启动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,1023,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 {
...
//通过参数fork SystemServer
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 */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//这里继续处理SystemServer相关
handleSystemServerProcess(parsedArgs);
}
return true;
}
先看参数部分String args[]没有配置--invoke-with
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
//内部类
static class Arguments {
/** from --invoke-with */
String invokeWith;
Arguments(String args[]) throws IllegalArgumentException {
parseArgs(args);
}
private void parseArgs(String args[])
throws IllegalArgumentException {
int curArg = 0;
boolean seenRuntimeArgs = false;
for ( /* curArg */ ; curArg < args.length; curArg++) {
String arg = args[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (arg.startsWith("--setuid=")) {
...
//所以invokeWith是null
} else if (arg.equals("--invoke-with")) {
if (invokeWith != null) {
throw new IllegalArgumentException(
"Duplicate arg specified");
}
try {
invokeWith = args[++curArg];
} catch (IndexOutOfBoundsException ex) {
throw new IllegalArgumentException(
"--invoke-with requires argument");
}
}
}
handleSystemServerProcess继续处理SystemServer
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
...
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
//最终执行这
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
//重点来到RuntimeInit
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();//native一些初始化,包含binder
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
再看看RuntimeInit
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
//各种通用初始化
protected static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);
LogManager.getLogManager().reset();
new AndroidConfig();
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
NetworkManagementSocketTagger.install();
String trace = SystemProperties.get("ro.kernel.android.tracing");
if (trace.equals("1")) {
Slog.i(TAG, "NOTE: emulator trace profiling enabled");
Debug.enableEmulatorTraceOutput();
}
initialized = true;
}
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//关键在这
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
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) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
//抛出了异常
throw new Zygote.MethodAndArgsCaller(m, argv);
}
ZygoteInit.java的main方法catch了这个异常,然后执行了run
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
}
}
public static class MethodAndArgsCaller extends Exception
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 {
//简单的invoke方法
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);
}
}
}
综上所示,最终执行了SystemServer的main方法
ZygoteServer都做了什么
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
class ZygoteServer {
public static final String TAG = "ZygoteServer";
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
private LocalServerSocket mServerSocket;
ZygoteServer() {
}
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) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
//创建Socker
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
...
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 {
//阻塞操作一直到pollFds发生变化,则往下走,有点像handler
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
//判断socket是否有变化,有变化继续执行
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);
}
}
}
}
}
}
到这Zygote的启动就告一段落了,接下来还有很重要的SystemServer,以及binder创建,还有AMS创建Activity联动,后续分析
以上是关于Android系统启动——Zygote启动的主要内容,如果未能解决你的问题,请参考以下文章
Android 进阶——系统启动之Android进程造物者Zygote 进程启动详解