「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
android手机在启动时,会从rom中加载引导程序到ram中,然后初始化硬件参数等资源,然后会加载Linux内核到Ram中。Kernel接着会启动init祖先进程,在init进程中会解析init.rc等配置文件,接着就会开启zygote进程。
由于水平有限,先跳过Init进程解析init.rc的过程。直接看init进程中调用的app_main.cpp中main()函数
下面是cpp_main.cpp的main函数。点击查看app_main.cpp的源码
源码基于android API 31
int main(int argc, char* const argv[])
{
//....省略部分代码
// 可以看到下面这些变量是控制启动zygote,systemServer的标志
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++];
//比较进程名是否是“--zygote"
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;
}
}
//......省略了部分代码
//主要流程。
if (zygote) {
//上面会对当前进程名比较是否是“--zygote",是则zygote = true,则会调用AndroidRuntime.start()
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.");
}
}
复制代码
**可以看到main函数最后会调用androidRuntime的start方法。下面再分析androidRuntime的start方法 **
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
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, primary_zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
*根据'className'调用main函数(根据app_main.cpp中的main函数发现调用了RuntimeInit和ZygoteInit中的main函数)
* 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 {
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
}
}
}
复制代码
下面开始进入java类中ZygoteInit的main方法
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
//......
try {
//......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
//......
}
//......
} catch (Throwable ex) {
//......
} finally {
//......
}
//......
}
}
}
复制代码
从下面的方法可以看到,通过forkSystemServer方法来fork SystemServer进程:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
//......
int pid;
try {
ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
try {
//.....
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//......
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
下面是Zygote类中的forkSystemServer静态方法
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
//可以看到,在Zygote中通过调用JNI本地方法,fork出SystemServer进程
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
//.....
return pid;
}
复制代码
在forkSystem最后一行代码可以发现在fork出子进程后,if (pid == 0)则执行handleSystemServerProcess(parsedArgs)
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
//......
if (parsedArgs.invokeWith != null) {
//......
} else {
//......
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
复制代码
紧跟着调用了ZygoteInit的zygoteInit方法:
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
//......
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
// 接着调用 findStaticMain
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
//.....
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
**//当前的className是SystemServer,所以接着通过JNI反射调用SystemServer的Main方法:
**protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
//....
return new MethodAndArgsCaller(m, argv);
}
复制代码
下面再来看SystemServer的main方法
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// 检查工厂测试模式。
mFactoryTestMode = FactoryTest.getMode();
// Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
//记住,它是运行时重启(当sys.boot_completed已设置)还是重新引导
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
mRuntimeStartUptime = SystemClock.uptimeMillis();
}
private void run() {
try {
//如果设备时钟在1970之前,则重新赋值为1970
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//如果没有设置时区,默认为格林威治时间(GMT)
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
SystemProperties.set("persist.sys.timezone", "GMT");
}
//检查设置语言环境
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
//系统服务器不应该进行非单向调用
Binder.setWarnOnBlocking(true);
//系统服务器应该始终加载安全标签
PackageItemInfo.setForceSafeLabels(true);
//停用SQLiteCompatibilityWalFlags,直到初始化设置提供程序
SQLiteCompatibilityWalFlags.init(null);
//----------此处开始进入Android系统服务-----------
int uptimeMillis = (int) SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
}
//如果自上次引导以来运行时发生切换(例如什么时候)在OTA中删除旧的运行时),则设置系统属性,使其同步
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
//更多内存
VMRuntime.getRuntime().clearGrowthLimit();
//系统服务器必须一直运行,因此需要尽可能高效地使用内存。
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//有些设备依赖于运行时指纹生成,因此在进一步引导之前请确保我们已经定义了它。
Build.ensureFingerprintProperty();
//在系统服务器中,在没有显式指定用户的情况下访问环境路径是错误的。
Environment.setUserRequired(true);
//在系统服务器中,任何传入的包都应该被解除锁定,以避免抛出BadParcelableException。
BaseBundle.setShouldDefuse(true);
//在系统服务器中,当打包异常时,包括堆栈跟踪
Parcel.setStackTraceParceling(true);
//确保对系统的绑定调用始终以前台优先级运行。
BinderInternal.disableBackgroundScheduling(true);
//增加system_server中绑定器线程的数量
BinderInternal.setMaxThreads(sMaxBinderThreads);
//准备创建主线程(当前线程).
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper(); //创建主线程
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
//加载libandroid_servers.so库
System.loadLibrary("android_servers");
//检查我们上次试着关闭时是否失败
performPendingShutdown();
//初始化系统上下文
createSystemContext();
//创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//为可以并行化的init任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd();
}
//开启系统服务
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
throw ex;
} finally {
traceEnd();
}
//......
//开启主线程,进入死循环,处理各种事件消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
//此处稍微注意,全局上下文是通过ActivityThread创建的
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
复制代码
以上的run方法大概可以分为下面几步:
首先设置时间、市区、语言等环境,然后设置虚拟机的一些属性参数 然后调用Looper.prepareMainLooper()创建主线程,即我们熟知的UI线程 接着加载android_servers底层库,初始化系统上下文对象 再接着就是初始化各种系统服务,例如:SystemServiceManager、ActivityServiceManager、WifiService等 最后调用Looper.loop()开启死循环,以处理各种事件消息 以上就是zygote进程到SystemServer进行的过程。