Android zygote

一、zygote介绍

在Android系统中,zygote是一个native进程,是Android系统上所有应用进程的父进程,我们系统上app的进程都是由这个zygote分裂出来的。zygote则是由Linux系统用户空间的第一个进程——init进程,通过fork的方式创建的。

zygote进程做了两个重要的事情:

1. 不断接收其它进程的信号,随时创建子进程(即app进程)

2. 创建了嫡长子 —— system_server进程

zygote进程启动之后,首先创建了Java虚拟机,该虚拟机是Android系统启动后的第一个虚拟机,然后注册JNI调用,接着调用了Java层的ZygoteInit类的main函数,进入了Java的世界。接着,Java世界的ZygoteInit开始了zygote的工作,工作的步骤按顺序如下:

1) 建立一个Socket服务端,监听客户端的连接,用于IPC通信。

这里是为了响应创建子进程的请求,当收到请求时,zygote执行一系列操作,最后通过fork创建子进程,请求是在第4)步启动循环后处理的。举个例子,应用程序A通过startActivity启动了应用程序B的Activity,但此时B进程并未启动,那么,A将利用Binder机制向系统的ActivityManagerService服务发送启动Activity的请求,而ActivityManagerService服务驻留在system_server进程,因此A将把请求发往system_server进程,system_server进程进而新建一个LocalSocket与zygote的ServerSocket进行连接,向zygote进程发送启动子进程的请求,并带上参数“android.app.ActivityThread”,zygote收到请求后通过fork的方式启动了子进程,并执行子进程的android.app.ActivityThread类中的main()函数,完成了应用程序B的进程的创建。

2)预加载类和资源

预加载类:系统有一个文件列表,保存着需要由zygote进行预加载的类的全路径,这些类是framework/base/tools/preload工具判断的加载时间超过1250微秒的类,zygote通过Class.forName()的方式进行预加载。这个列表不小,每一行一个类,超过了1000行,这也是Android系统启动慢的原因之一。

zygote预加载类的一个好处是:预加载一次类后,在通过fork创建子进程时,只需要做一个复制即可,这样便加快了子进程的启动速度。

预加载资源:主要是加载framework-res.apk中的资源,在UI编程中常使用的com.android.R.XXX资源,是系统默认的资源,它们就是由zygote加载的。

3)通过fork的方式,启动system_server进程

system_server进程是zygote进程创建的第一个进程,也就是“嫡长子”,其中驻留着Android系统多个重要的服务,比如EntropyService、PowerManagerService、BatteryService、WindowManagerService、ActivityManagerService等。

zygote进程内部通过函数startSystemServer()启动system_server进程,该函数采用了抛出异常后在异常捕获处继续执行的技巧,使得system_server进程跳过了zygote进程后续的步骤进入system_server的Java世界,这些步骤包括使得Zygote进入无限循环的runSelectLoopMode()方法。

system_server的一个重要的特点是,它支持使用Binder进行进程间通信,它已经进入了Binder的世界,不用跟zygote进程一样使用Socket。

另一个特点是,system_server是和zygote共存亡的,只要system_server被杀死,zygote也会把自己杀掉,这就导致了系统的重启。

4)通过调用runSelectLoopMode()方法,进入无限循环,等待客户端的连接请求,并处理请求。

这里可以发现,无论是zygote进程,还是system_server进程,或者是zygote分裂的应用子进程,他们的模式都是在进行必要的native初始化后,随即调用Java层某个类的main函数,从而进入Java的世界,主要逻辑都是在Java层完成。比如zygote进程的ZygoteInit.java类、system_server进程的SystemServer.java类、应用子进程的ActivityThread.java类

二、zygote相关文件和类

AppRuntime

app_main.cpp是一个C++文件,位于Android源代码的/frameworks/base/cmds/app_process/目录下。它是Android系统中的一个重要文件,用于启动Android应用程序的进程。

AppRuntime文件路径:

frameworks/base/cmds/app_process/app_main.cpp

AppRuntime定义:

class AppRuntime : public AndroidRuntime {}

方法:

int main(int argc, char* const argv[])

static void maybeCreateDalvikCache()

static size_t computeArgBlockSize(int argc, char* const argv[])

AppRuntime方法:

AppRuntime(char* argBlockStart, const size_t argBlockLength):构造方法

void setClassNameAndArgs(const String8& className, int argc, char * const *argv)

virtual void onVmCreated(JNIEnv* env)

virtual void onStarted()

virtual void onZygoteInit()

virtual void onExit(int code)

AndroidRuntime

AndroidRuntime文件路径:

frameworks/base/core/jni/AndroidRuntime.cpp

frameworks/base/core/jni/include/android_runtime/AndroidRuntime.h

AndroidRuntime定义:

class AndroidRuntime {}

AndroidRuntime方法:

AndroidRuntime(char* argBlockStart, size_t argBlockSize)

static int registerNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods):Register a set of methods in the specified class.

status_t callMain(const String8& className, jclass clazz, const Vector<String8>& args):Call a class's static main method with the given arguments,

static jclass findClass(JNIEnv* env, const char* className):Find a class, with the input either of the form "package/class" or "package.class".

void start(const char *classname, const Vector<String8>& options, bool zygote);

void exit(int code);

static AndroidRuntime* getRuntime();

virtual void onVmCreated(JNIEnv* env):This gets called after the VM has been created, but before we run any code. Override it to make any FindClass calls that need to use CLASSPATH.

virtual void onStarted():This gets called after the JavaVM has initialized. Override it with the system's native entry point.

virtual void onZygoteInit():This gets called after the JavaVM has initialized after a Zygote fork. Override it to initialize threads, etc. Upon return, the correct static main will be invoked.

virtual void onExit(int /*code*/) :Called when the Java application exits to perform additional cleanup actions before the process is terminated.

static android_thread_id_t createJavaThread(const char* name, void (*start)(void *), void* arg):create a new thread that is visible from Java

static JavaVM* getJavaVM():return a pointer to the VM running in this process

static JNIEnv* getJNIEnv():return a pointer to the JNIEnv pointer for this thread

static char* toSlashClassName(const char* className):return a new string corresponding to 'className' with all '.'s replaced by '/'s.

static jstring NewStringLatin1(JNIEnv* env, const char* bytes):Create a Java string from an ASCII or Latin-1 string

ZygoteInit

ZygoteInit是Android系统中的一个关键类,它在系统启动时负责创建和管理Zygote进程。Zygote进程是Android系统中的一个特殊进程,它作为其他应用进程的父进程,负责创建和孵化新的应用进程。

ZygoteInit类的主要作用是初始化Zygote进程,并根据命令行参数来决定是否启动系统服务。在main方法中,它首先注册Zygote进程的套接字,然后根据命令行参数来决定是否启动系统服务。如果命令行参数的第二个参数为"true",则启动系统服务;如果不为"true"也不为"false",则执行其他逻辑。最后,根据ZYGOTE_FORK_MODE的值来决定是运行选择循环模式还是执行其他逻辑。

ZygoteInit文件路径:

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

ZygoteInit定义:

public class ZygoteInit {}

ZygoteInit方法:

public static void main(String[] argv) : This is the entry point for a Zygote process.

static void initNativeState(boolean isPrimary):Initialize the native state of the Zygote.

private static void gcAndFinalize() :Runs several special GCs to try to clean up a few generations of softly- and final-reachable objects, along with any other garbage. This is only useful just before a fork().

private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer):Prepare the arguments and forks for the system server process.

ZygoteServer

ZygoteServer的主要作用是监听来自SystemServer和其他进程的连接请求,并根据请求创建新的应用进程。

ZygoteServer文件路径:

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

ZygoteServer定义:

class ZygoteServer {}

ZygoteServer方法:

ZygoteServer(boolean isPrimaryZygote) :构造方法

private ZygoteConnection acceptCommandPeer(String abiList) :Waits for and accepts a single command connection.

void closeServerSocket() :Close and clean up zygote sockets.

Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill):Refill the USAP Pool to the appropriate level, determined by whether this is a priority refill event or not.

Runnable setUsapPoolStatus(boolean newStatus, LocalSocket sessionSocket):Empty or fill the USAP pool as dictated by the current and new USAP pool statuses.

Runnable runSelectLoop(String abiList):Runs the zygote process's select loop. Accepts new connections as they happen, and reads commands from connections one spawn-request's worth at a time.

zygote

zygote文件路径:

frameworks/base/core/java/com/android/internal/os/zygote.java

zygote定义:

public final class Zygote {}

zygote方法:

static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,

int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,

int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,

boolean isTopApp, String[] pkgDataInfoList, String[] allowlistedDataInfoList,

boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs):Forks a new VM instance.

private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,

int[][] rlimits, int mountExternal, String seInfo, String niceName,

boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,

String[] pkgDataInfoList, String[] allowlistedDataInfoList,

boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs):Specialize an unspecialized app process.

static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities):Special method to start the system server process.

static void allowAppFilesAcrossFork(ApplicationInfo appInfo):Lets children of the zygote inherit open file descriptors that belong to the ApplicationInfo that is passed in.

static void markOpenedFilesBeforePreload():Scans file descriptors in /proc/self/fd/, stores their metadata from readlink(2)/stat(2) when available. Saves this information in a global on native side, to be used by subsequent call to allowFilesOpenedByPreload().

static void allowFilesOpenedByPreload() :By scanning /proc/self/fd/ determines file descriptor numbers in this process opened since the first call to markOpenedFilesBeforePreload().

static void initNativeState(boolean isPrimary):Initialize the native state of the Zygote.

public static String getConfigurationProperty(String propertyName, String defaultValue) :Returns the raw string value of a system property.

public static boolean getConfigurationPropertyBoolean(String propertyName, Boolean defaultValue):Returns the value of a system property converted to a boolean using specific logic.

static FileDescriptor getUsapPoolEventFD():return The event FD used for communication between the signal handler and the ZygoteServer poll loop

static @Nullable Runnable forkUsap(LocalServerSocket usapPoolSocket, int[] sessionSocketRawFDs, boolean isPriorityFork) :Fork a new unspecialized app process from the zygote.

static @Nullable Runnable forkSimpleApps(@NonNull ZygoteCommandBuffer argBuffer, @NonNull FileDescriptor zygoteSocket, int expectedUid, int minUid, @Nullable String firstNiceName):Fork a new app process from the zygote.

private static Runnable childMain(@Nullable ZygoteCommandBuffer argBuffer, @Nullable LocalServerSocket usapPoolSocket, FileDescriptor writePipe):Specialize the current process into one described by argBuffer or the command read from usapPoolSocket.

private static void validateUsapCommand(ZygoteArguments args):Checks a set of zygote arguments to see if they can be handled by a USAP.

static boolean removeUsapTableEntry(int usapPID):Remove the USAP table entry for the provided process ID.

static int minChildUid(Credentials peer) :Return the minimum child uid that the given peer is allowed to create.

static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer):Adjust uid and gid arguments, ensuring that the security policy is satisfied.

static void applyDebuggerSystemProperty(ZygoteArguments args) :Applies debugger system properties to the zygote arguments.

static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer): Applies zygote security policy.

public static String getWrapProperty(String appName):Gets the wrap property if set.

static LocalServerSocket createManagedSocketFromInitSocket(String socketName):Creates a managed LocalServerSocket object using a file descriptor created by an init.rc script.

static void appendQuotedShellArgs(StringBuilder command, String[] args):Appends quotes shell arguments to the specified string builder.

static void execShell(String command) :Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.

AppZygote

AppZygote is responsible for interfacing with an application-specific zygote.

AppZygote 负责与特定于应用程序的 zygote 进行交互。

AppZygote文件路径:

frameworks/base/core/java/android/os/AppZygote.java

AppZygote定义:

public class AppZygote {}

AppZygote方法:

public AppZygote(ApplicationInfo appInfo, ProcessInfo processInfo, int zygoteUid, int uidGidMin, int uidGidMax):构造方法

public ChildZygoteProcess getProcess():Returns the zygote process associated with this app zygote.

public void stopZygote():Stops the Zygote and kills the zygote process

public ApplicationInfo getAppInfo()

ZygoteProcess

Maintains communication state with the zygote processes.

ZygoteProcess文件路径:

frameworks/base/core/java/android/os/ZygoteProcess.java

ZygoteProcess定义:

public class ZygoteProcess {

        private static class ZygoteState implements AutoCloseable {}

}

ZygoteProcess方法:

public final Process.ProcessStartResult start(@NonNull final String processClass, final String niceName, int uid, int gid, @Nullable int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion,@Nullable String seInfo, @NonNull String abi, @Nullable String instructionSet, @Nullable String appDataDir, @Nullable String invokeWith, @Nullable String packageName, int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, @Nullable Map<String, Pair<String, Long>> allowlistedDataInfoList, boolean bindMountAppsData, boolean bindMountAppStorageDirs, @Nullable String[] zygoteArgs):Start a new process.

private Process.ProcessStartResult startViaZygote(@NonNull final String processClass, @Nullable final String niceName, final int uid, final int gid, @Nullable final int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, @Nullable String seInfo, @NonNull String abi, @Nullable String instructionSet, @Nullable String appDataDir, @Nullable String invokeWith, boolean startChildZygote, @Nullable String packageName, int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, @Nullable Map<String, Pair<String, Long>> allowlistedDataInfoList, boolean bindMountAppsData, boolean bindMountAppStorageDirs, @Nullable String[] extraArgs):Starts a new process via the zygote mechanism.

private ZygoteState openZygoteSocketIfNeeded(String abi)

private Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(ZygoteState zygoteState, String msgStr)

ChildZygoteProcess

Represents a connection to a child-zygote process.

ChildZygoteProcess文件路径:

frameworks/base/core/java/android/os/ChildZygoteProcess.java

ChildZygoteProcess定义:

public class ChildZygoteProcess extends ZygoteProcess {}

ZygoteConnection

A connection that can make spawn requests.

可以发出生成请求的连接。

ZygoteConnection文件路径:

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

ZygoteConnection定义:

class ZygoteConnection {}

ZygoteConnection方法:

ZygoteConnection(LocalSocket socket, String abiList):构造方法

Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK):Reads a command from the command socket.

WrapperInit

WrapperInit是一个在Android系统中的关键组件,它在系统启动过程中起到了重要的作用。它的主要功能是在Zygote进程中初始化运行时环境。

WrapperInit文件路径:

frameworks/base/core/java/com/android/internal/os/WrapperInit.java

WrapperInit定义:

public class WrapperInit {}

WrapperInit方法:

private WrapperInit() :构造方法

public static void main(String[] args) :主函数

public static void execApplication(String invokeWith, String niceName, int targetSdkVersion, String instructionSet, FileDescriptor pipeFd, String[] args) :使用包装器命令执行 Runtime 应用程序。

private static Runnable wrapperInit(int targetSdkVersion, String[] argv):通过包装进程启动应用程序时调用的 main 函数。

private static void preserveCapabilities() :将当前功能复制到环境功能。

RuntimeInit

RuntimeInit是Android系统中的一个类,它负责在应用程序启动时进行一些初始化工作。具体来说,RuntimeInit类的主要职责是执行一系列的初始化方法,以确保应用程序能够正常运行。

RuntimeInit文件路径:

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

RuntimeInit定义:

public class RuntimeInit {

        private static class LoggingHandler implements Thread.UncaughtExceptionHandler {}

        private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {}

        static class Arguments {} //处理与运行时相关的参数的参数分析

        static class MethodAndArgsCaller implements Runnable {}

}

RuntimeInit方法:

public static void preForkInit() : Common initialization that (unlike {@link #commonInit()} should happen prior to the Zygote fork.

protected static final void commonInit()

private static String getDefaultUserAgent()

protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader)

public static final void main(String[] argv)

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges, String[] argv, ClassLoader classLoader)

public static void wtf(String tag, Throwable t, boolean system)

public static void setDefaultApplicationWtfHandler(final ApplicationWtfHandler handler)

public static final void setApplicationObject(IBinder app)

public static final IBinder getApplicationObject()

protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader):在类“className”上调用静态“main(argv[])方法。

三、zygote相关流程分析

zygote启动流程分析

Android Zygote启动流程分析-CSDN博客

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值