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 Zygote 从何而来?揭开Android系统启动的面纱
Android 进阶——系统启动之Android进程造物者Zygote 进程启动详解