一、Zygote servcie的配置
在上一篇中,我们知道zygote进程是在`/system/etc/init/hw/init.rc`文件中配置,由init进程启动的。看下init中关于zygote的配置:
...
import /system/etc/init/hw/init.${ro.zygote}.rc
...
on late-init
...
trigger zygote-start
on zygote-start
// 等待签名校验完成
// platform\system\security\ondevice-signing\odsign_main.cpp
wait_for_prop odsign.verification.done 1
// 启动用于标识(A/B)更新完成的守护进程
exec_start update_verifier
// 启动收集性能指标的statsd服务
start statsd
// 启动网络管理模块
start netd
// 启动zygote
start zygote
start zygote_secondary
on userspace-reboot-resume
...
trigger zygote-start
其中第一句import /system/etc/init/hw/init.${ro.zygote}.rc中的ro.zygote为属性,从源码看,对应的文件:core/rootdir/init.zygote64.rc、core/rootdir/init.zygote32.rc和init.zygote64_32.rc。具体是哪一个,可以在实际系统中getprop ro.zygote查看。这里以core/rootdir/init.zygote64_32.rc(兼容64和32位)为例:
import /system/etc/init/hw/init.zygote64.rc
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
task_profiles ProcessCapacityHigh MaxPerformance
首行所import的init.zygote64.rc内容为:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
// 指定class为main。可通过class_start main来启动所有class为main的service
class main
// 优先级
priority -20
// 设置进程user
user root
// 设置进程gorup
group root readproc reserved_disk
// 创建一个名为zygote的socket服务端,用于接收孵化新进程的请求
socket zygote stream 660 root system
// 创建usap_pool_primary socket。用于以usap方式孵化进程
socket usap_pool_primary stream 660 root system
// 下面是在onrestart时执行的一些列指令
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
# NOTE: If the wakelock name here is changed, then also
# update it in SystemSuspend.cpp
onrestart write /sys/power/wake_lock zygote_kwl
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart --only-if-running media.tuner
onrestart restart netd
onrestart restart wificond
// 设置cgroup
task_profiles ProcessCapacityHigh MaxPerformance
// 本服务对设备来说是至关重要的。如果在window指定的分钟数(默认为4)内crash超过4次,则重启进入target指定模式(默认为bootloader,即fastboot)。
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
从前两篇init.rc的处理过程解析我们知道,如上的声明,执行的过程为:
1)init.zygote64_32.rc里的service zygote.. 、service zygote_secondary被解析后加入service队列等待执行
2)late-init这个trigger被触发,随后继续触发zygote-start,然后从上到下依次执行zygote-start下的每个Command,并最终执行两个zygote服务。
我们看64位的service zygote:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
zygote:service的名称,注意这里并非是进程名称,而是init进程内部标识service的name。
/system/bin/app_process64:指定了可执行文件的路径。
-Xzygote:是传递给虚拟机的参数,告诉虚拟机是否已zygote模式启动。这里实际影响的是虚拟机启动时是否加载boot.art内存映射文件,即预加载常用的系统类。具体实现的代码路径:
app_main.cpp
runtime.start
AndroidRuntime.cpp
startVm(&mJavaVM, &env, zygote, primary_zygote)
java_vm_ext.cc
JNI_CreateJavaVM
runtime.cc
bool Runtime::Create(RuntimeArgumentMap&& runtime_options
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in)
Opt runtime_options(std::move(runtime_options_in))
gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize)
heap.cc
space::ImageSpace::LoadBootImage(boot_class_path,
image_space.cc
bool ImageSpace::LoadBootImage(const std::vector<std::string>&
BootImageLayout::LoadFromSystem(
ImageSpace::BootImageLayout::Load
/system/bin:目前实际没有使用到
--zygote:app_process64内部有两种启动模式,--zygote指定启动类为com.android.internal.os.ZygoteInit。另一种则启动com.android.internal.os.RuntimeInit。
--start-system-server:指明启动system server
--socket-name:指定作为客户端要连接的服务端zygote名称。首先zygote service在启动时,先根据下面option的声明`socket zygote stream 660 root system`创建一个服务端的socket,名称为zygote。随后再启动作为zygote的app_process64进程。启动进程的过程中,会根据--socket-name参数指定的名称,创建socket客户端去连接服务端。我们知道zygote是app进程的孵化器,被孵化的子进程将继承这个客户端的socket,与服务端通信。
service zygote下的options:
class main是在某些时候,比如init将文件系统挂载后,通过class_start main启动所有class为main的服务。class同为main的service还有storaged、netd等service。
priority和task_profiles是为zygote进程分配了优先级较高的cpu资源,同时保证在内存紧张时不会被回收
socket zygote和usap_pool_primary,是建立了两种孵化进程方式的通道。除了传统的zygote孵化方式,从Android Q开始,新增了usap方式,可以预创建一个进程池,在孵化app进程时更加高效。
而一系列的onrestart,则是在zygote进程意外退出被init重启的情况下,需要一同启动的一系列基础服务servcie,如audioserver、cameraserver、media等等。
二、Zygote进程的启动
/system/bin/app_process64的源码在app_main.cpp, 入口为main函数
platform/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
// 虚拟机runtime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
// 将虚拟机参数-XZytote放入runtime.addOption
for (i = 0; i < argc; i++) {
if (argv[i][0] != '-') {
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
}
// 解析跟zygote本身有关的参数
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
// 如果设置--zygote参数,则把进程名设置为ZYGOTE_NICE_NAME,也就是zygote64
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 = (arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className = arg;
break;
} else {
--i;
break;
}
}
if (!className.empty()) {
// zygote模式不走此分支
} else {
// 创建/data/dalvik-cache/"ABI(cpu架构)"目录
maybeCreateDalvikCache();
// 将rc里的参数整理到args里
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=");
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.empty()) {
runtime.setArgv0(niceName.c_str(), true /* setProcName */);
}
// 启动ZygoteInit,传入args参数
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (...) {
...
}
...
}
上面的代码做了几件事:
- 创建AppRuntime runtime
- 解析以‘-’开头的虚拟机参数,传给runtime
- 解析以‘--’开头的zygote参数
- 创建/data/dalvik-cache/目录
- 通过runtime.start启动ZygoteInit。
AppRuntime是AndroidRuntime的子类,直接看AndroidRuntime的start:
core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
static const String8 startSystemServer("start-system-server");
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
primary_zygote = true;
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
...
// 初始化虚拟机对象
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
// 加载ZygoteInit类
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
// 将第一个参数设置为类名
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).c_str());
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.
*/
char* slashClassName = toSlashClassName(className != NULL ? 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 {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
}
看下初始化虚拟机的函数startVm
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote)
{
JavaVMInitArgs initArgs;
...
处理一系列参数
...
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\n");
return -1;
}
}
上面的代码,就是启动了一个虚拟机,加载ZygoteInit,执行其main方法。
看下ZygoteInit的main:
core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
// 在zygote中不可创建thread
ZygoteHooks.startZygoteNoThreadCreation();
// 一些在zygote fork前要做的工作,比如mimeType文件映射
RuntimeInit.preForkInit();
// 解析service参数
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
// --abi-list=
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
// --socket-name=
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (!enableLazyPreload) {
...
// 预加载
preload(bootTimingsTraceLog);
}
// 在fork前做一波gc
gcAndFinalize();
// 初始化zygote的native状态,包括获取socket的fd,初始化security properties,卸载 /storage目录,初始化用于cgroup设置的TaskProfiles对象等
Zygote.initNativeState(isPrimaryZygote);
// 解除不允许创建线程的限制
ZygoteHooks.stopZygoteNoThreadCreation();
// 初始化ZygoteServer。实际上是init.rc里那个服务端socket的封装
zygoteServer = new ZygoteServer(isPrimaryZygote);
// 开始孵化SystemServer
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
// 监听sock请求,fork新的进程
caller = zygoteServer.runSelectLoop(abiList);
}
在main方法中,主要做了以下事情:
- 通过RuntimeInit.preForkInit();初始化mimeType文件映射
- 在preload方法中作了一些预加载的工作,其中包括Locale、DecimalFormatData、SimpleDateFormatData的初始化;常用基础类的初始化;资源的初始化;android so库的加载等等。
- Zygote.initNativeState进行了native层面的一些初始化工作,如卸载/storage、初始化cgroup的TaskProfiles等
- 启动SystemServer
- 监听socket请求,收到请求后fork新的进程。
- preload
看下比较重要的部分preload(bootTimingsTraceLog);
platform/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
bootTimingsTraceLog.traceBegin("BeginPreload");
// 初始化Locale、DecimalFormatData、SimpleDateFormatData等
beginPreload();
bootTimingsTraceLog.traceEnd(); // BeginPreload
bootTimingsTraceLog.traceBegin("PreloadClasses");
// 预加载类
preloadClasses();
bootTimingsTraceLog.traceEnd(); // PreloadClasses
bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
// 缓存非boot的class
cacheNonBootClasspathClassLoaders();
bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
bootTimingsTraceLog.traceBegin("PreloadResources");
// 预加载资源
Resources.preloadResources();
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
// hal层初始化
nativePreloadAppProcessHALs();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
// 渲染引擎相关初始化
maybePreloadGraphicsDriver();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
preloadSharedLibraries();
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
endPreload();
warmUpJcaProviders();
Log.d(TAG, "end preload");
sPreloadComplete = true;
}
- 预加载类:preloadClasses(BootClassLoader)
private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
private static void preloadClasses() {
...
is = new FileInputStream(PRELOADED_CLASSES);
...
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);
...
String line;
while ((line = br.readLine()) != null) {
Class.forName(line, true, null);
count++;
...
}
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
IoUtils.closeQuietly(is);
// 当前并未有具体实现
runtime.preloadDexCaches();
if (isExperimentEnabled("profilebootclasspath")) {
// 重置JitCounters,在预加载后,重新计算method counter,为profile提供依据。
VMRuntime.resetJitCounters();
}
}
如上代码,预加载的类在/system/etc/preloaded-classes文件中声明,即所谓的BootClassPath类。读取该文件每行类名,通过Class.forName进行加载。
这里声明的只是类名,而不是类本身所在的dex。BootClassPath类本身所在的dex可通过环境变量$BOOTCLASSPATH查看。
首先,在虚拟机初始化时,Runtime::Init函数会通过OpenBootDexFiles加载$BOOTCLASSPATH指定的dex文件,随后如上Zygote启动时根据/preloaded-classes里的名单加载具体类。
我们通常说Android里的ClassLoader有三层:BootClassLoader、PathClassLoader、DexClassLoader。BootClassLoader加载了Java基础jre类,PathClassLoader加载了android的system系统类、Application应用所需基础类。DexClassClassLoader可以用来在app运行时动态加载dex,是用户层面的ClassLoader。而上面所描述的preloadClasses,就是BootClassLoader创建、启动、加载jre类的过程。至于PathClassLoader,我们在下面的SystemServer启动过程中可以看到。
- 预加载资源preloadResources
public static void preloadResources() {
final Resources sysRes = Resources.getSystem();
sysRes.startPreloading();
TypedArray ar = sysRes.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
int numberOfEntries = preloadDrawables(sysRes, ar);
ar = sysRes.obtainTypedArray(com.android.internal.R.array.preloaded_color_state_lists);
numberOfEntries = preloadColorStateLists(sysRes, ar);
ar = sysRes.obtainTypedArray(com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
numberOfEntries = preloadDrawables(sysRes, ar);
}
首先,Resources.getSystem()中,加载了/system/framework/framework-res.apk
platform/frameworks/base/core/java/android/content/res/Resources.java
public static Resources getSystem() {
synchronized (sSync) {
Resources ret = mSystem;
if (ret == null) {
ret = new Resources();
mSystem = ret;
}
return ret;
}
}
private Resources() {
this(null);
final DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
final Configuration config = new Configuration();
config.setToDefaults();
mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
new DisplayAdjustments());
}
platform/frameworks/base/core/java/android/content/res/AssetManager.java
private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";
public static AssetManager getSystem() {
synchronized (sSync) {
createSystemAssetsInZygoteLocked(false, FRAMEWORK_APK_PATH);
return sSystem;
}
}
随后,从platform/frameworks/base/core/res/res/values/arrays.xml下,预加载preloaded_drawables、preloaded_color_state_lists、preloaded_freeform_multi_window_drawables等资源。
- nativePreloadAppProcessHALs初始化hal层
- preloadSharedLibraries: 加载so
private static void preloadSharedLibraries() {
Log.i(TAG, "Preloading shared libraries...");
System.loadLibrary("android");
System.loadLibrary("jnigraphics");
// TODO(b/206676167): This library is only used for renderscript today. When renderscript is
// removed, this load can be removed as well.
if (!SystemProperties.getBoolean("config.disable_renderscript", false)) {
System.loadLibrary("compiler_rt");F
}
}
- preloadTextResources 加载字体
- WebViewFactory.prepareWebViewInZygote(); webview预申请内存空间
- warmUpJcaProviders 安装Jca密码学架构 的provider
三、SystemServer的启动
- forkSystemServer
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
String[] args = {
"--setuid=1000",
"--setgid=1000",
// 进程组 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
"--capabilities=" + capabilities + "," + capabilities,
// 进程名
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
// SystemServer的启动类
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs;
int pid;
try {
ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
try {
parsedArgs = ZygoteArguments.getInstance(commandBuffer);
} catch (EOFException e) {
throw new AssertionError("Unexpected argument error for forking system server", e);
}
commandBuffer.close();
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
pid = Zygote.forkSystemServer(
...
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
首先,我们关注下args参数:
setgroups设定SystemServer的进程组,这个在调查SystemServer有那些权限的时候会需要。
nice-name设定进程名
com.android.server.SystemServer是入口类,在fork出一个新进程后,执行这个类才真正开始SystemServer的旅程。
我们看下Zygote.forkSystemServer做了什么:
platform/frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
platform/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 runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
jlong effective_capabilities) {
...
if (gUsapPoolEventFD != -1) {
fds_to_close.push_back(gUsapPoolEventFD);
fds_to_ignore.push_back(gUsapPoolEventFD);
}
...
pid_t pid = zygote::ForkCommon(env, true,
fds_to_close,
fds_to_ignore,
true);
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore,
bool is_priority_fork,
bool purge) {
auto fail_fn = std::bind(zygote::ZygoteFailure, env,
is_system_server ? "system_server" : "zygote",
nullptr, _1);
...
pid_t pid = fork();
...
本质上,调用了fork()创建了新进程
在fork了新进程后,调用handleSystemServerProcess来执行SystemServer:
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
if (parsedArgs.mNiceName != null) {
// 设置进程名system_server
Process.setArgV0(parsedArgs.mNiceName);
}
// 获取SystemServer的classpath,也就是jar文件所在路径
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
...
// 启动时SystemServer时不带这个参数
if (parsedArgs.mInvokeWith != null) {
...
} else {
// 创建pathclassloader
ClassLoader cl = getOrCreateSystemServerClassLoader();
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
getOrCreateSystemServerClassLoader创建了一个SystemServerClassLoader,或者我们叫PathClassLoader,也就是上文我们提到的第二层ClassLoader。我们看下其创建过程:
private static ClassLoader getOrCreateSystemServerClassLoader() {
if (sCachedSystemServerClassLoader == null) {
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
}
}
return sCachedSystemServerClassLoader;
}
Os.getenv("SYSTEMSERVERCLASSPATH")获取dex/jar文件所在路径。一般的值可能是这样的:
/system/framework/services.jar:/system/framework/ethernet-service.jar:/apex/com.android.appsearch/javalib/service-appsearch.jar:/apex/com.android.media/javalib/service-media-s.jar:/apex/com.android.permission/javalib/service-permission.jar
随后通过createPathClassLoader创建ClassLoader:
static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
String libraryPath = System.getProperty("java.library.path");
// We use the boot class loader, that's what the runtime expects at AOT.
ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
}
ClassLoader.getSystemClassLoader().getParent();返回的是BootClassLoader。看下ClassLoaderFactory.createClassLoader:
platform/frameworks/base/core/java/com/android/internal/os/ClassLoaderFactory.java
public static ClassLoader createClassLoader(String dexPath,
String librarySearchPath, ClassLoader parent, String classloaderName,
List<ClassLoader> sharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfter) {
ClassLoader[] arrayOfSharedLibraries = (sharedLibraries == null)
? null
: sharedLibraries.toArray(new ClassLoader[sharedLibraries.size()]);
ClassLoader[] arrayOfSharedLibrariesLoadedAfterApp = (sharedLibrariesLoadedAfter == null)
? null
: sharedLibrariesLoadedAfter.toArray(
new ClassLoader[sharedLibrariesLoadedAfter.size()]);
if (isPathClassLoaderName(classloaderName)) {
return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries,
arrayOfSharedLibrariesLoadedAfterApp);
} else if (isDelegateLastClassLoaderName(classloaderName)) {
return new DelegateLastClassLoader(dexPath, librarySearchPath, parent,
arrayOfSharedLibraries, arrayOfSharedLibrariesLoadedAfterApp);
}
throw new AssertionError("Invalid classLoaderName: " + classloaderName);
}
最后会走到return new PathClassLoader(...这一步。以上步骤简言之,就是通过Os.getenv("SYSTEMSERVERCLASSPATH");所指定的dex/jar文件,构建了一个PathClassLoader。
回到handleSystemServerProcess, 接下来调用ZygoteInit.zygoteInit
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
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();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
看RuntimeInit.applicationInit这一步。注意这里将之前的classloader、参数argv传了进去:
platform/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
final Arguments args = new Arguments(argv);
// 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
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
Arguments里,将之前的参数“com.android.server.SystemServer”解析了出来,放到了startClass属性里,因此findStaticMain的首个参数就是com.android.server.SystemServer
看下findStaticMain:
protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) {
...
cl = Class.forName(className, true, classLoader);
...
m = cl.getMethod("main", new Class[] { String[].class });
...
return new MethodAndArgsCaller(m, argv);
}
加载com.android.server.SystemServer类,然后调用其main方法。至此,SystemServer启动完毕。文章来源:https://www.toymoban.com/news/detail-835081.html
总结一下:文章来源地址https://www.toymoban.com/news/detail-835081.html
- init进程根据init.rc中配置的service zygote创建Zygote进程
- Zygote创建、初始化了虚拟机,创建了BootClassLoader
- 在preloadClasses中加载了BootClassPath下的dex,并加载了基础类
- 在preloadResource中加载了framework-res.apk,加载一些基本的drawable等资源
- fork并启动了SystemServer
- Zygote进程中创建了socket服务端,循环select检查客户端请求
到了这里,关于Android启动过程 - Zygote的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!