Android系统启动流程(基于Android 11),2024年来看看Android的发展

ALOGE(“JavaVM unable to locate class ‘%s’\n”, slashClassName);
} else {
// 3.JNI调用进入java层执行ZygoteInit的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);

}

}

从代码中可以看到AndroidRuntime#start方法中主要完成三件事情

  1. 启动进程的VM虚拟机;

  2. 注册Android系统框架JNI调用到虚拟机中;

  3. 通过JNI调用进入java层执行ZygoteInit的main函数

2.2 java层ZyogeInit

我们继续往下看简化的代码流程:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;

try {

for (int i = 1; i < argv.length; i++) {
if (“start-system-server”.equals(argv[i])) {
// 在init.rc文件中,有–start-system-server参数,表示要创建SystemServer
startSystemServer = true;
} else if (“–enable-lazy-preload”.equals(argv[i])) {
enableLazyPreload = true;
}

}

// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
if (!enableLazyPreload) {

preload(bootTimingsTraceLog);// 1.预加载资源

}

zygoteServer = new ZygoteServer(isPrimaryZygote); // 2.创建Socket服务端
if (startSystemServer) {
// 3.fork启动system_server进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

}
//4. sokcet服务端等待AMS请求(AMS会通过socket请求Zygote来创建应用程序进程)
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, “System zygote died with exception”, ex);
throw ex;
}

}

static void preload(TimingsTraceLog bootTimingsTraceLog) {

preloadClasses();// 1.加载system/etc/preloaded-classes文件中定义的各个系统类

preloadResources(); // 2.加载系统中定义的各个drawables、color资源

}

从代码中可以看到ZygoteInit#main方法中主要fork启动system_server进程:

  1. zygote进程中预加载类、主题资源、字体资源等,基于linux的copy-on-write机制,从而加速后续zygote fork创建出的应用进程的启动速度

  2. 创建socket服务端,用于跨进程通信;

  3. fork创建启动系统system_server进程;

  4. Sokcet服务端进入循环监听等待,等待后续AMS请求(AMS会通过socket请求Zygote来创建应用程序进程)。

3. system_server进程的启动

我们接着ZygoteInit#forkSystemServer往下看:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {

/* Hardcoded command line to start the system server */
// 1.构建启动system_server进程的相关设置参数
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,3006,3007,3009,3010,3011”,
    “–capabilities=” + capabilities + “,” + capabilities,
    “–nice-name=system_server”,
    “–runtime-args”,
    “–target-sdk-version=” + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
    // system_server启动的类名
    “com.android.server.SystemServer”,
    };

    try {

    /* Request to fork the system server process */
    // 2.fork创建system_server进程,具体实现在native层
    pid = Zygote.forkSystemServer(
    parsedArgs.mUid, parsedArgs.mGid,
    parsedArgs.mGids,
    parsedArgs.mRuntimeFlags,
    null,
    parsedArgs.mPermittedCapabilities,
    parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
    throw new RuntimeException(ex);
    }

/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}

zygoteServer.closeServerSocket();
// 3.pid为0代表在新创建的system_server进程中,继续通过handleSystemServerProcess进一步处理
return handleSystemServerProcess(parsedArgs);
}

return null;
}

/**

  • Finish remaining work for the newly forked system server process.
    /
    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {

    if (parsedArgs.mInvokeWith != null) {

    } else {

    /
  • Pass the remaining arguments to SystemServer.
    */
    // 调用ZygoteInit#zygoteInit函数具体处理
    return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
    parsedArgs.mDisabledCompatChanges,
    parsedArgs.mRemainingArgs, cl);
    }
    }

public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {

// 1.RuntimeInit初始化,通过setDefaultUncaughtExceptionHandler设置默认的异常处理机制
RuntimeInit.commonInit();
// 2.触发启动进程的Binder线程池
ZygoteInit.nativeZygoteInit();
// 3.内部经过层层调用,最终通过反射创建"com.android.server.SystemServer"类对象并执行其main函数
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}

继续结合代码看看RuntimeInit#applicationInit是如何实现反射创建"com.android.server.SystemServer"类对象并执行其main函数的:

/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java/
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {

return findStaticMain(args.startClass, args.startArgs, classLoader);
}

protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;

try {
// 1.通过反射加载构建"com.android.server.SystemServer"类对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}

Method m;
try {
//2.访问获取"com.android.server.SystemServer"的main方法
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);
}

/*

  • This throw gets caught in ZygoteInit.main(), which responds
  • by invoking the exception’s run() method. This arrangement
  • clears up all the stack frames that were required in setting
  • up the process.
    */
    // 3.通过抛异常触发执行main函数并清除调用栈
    return new MethodAndArgsCaller(m, argv);
    }

static class MethodAndArgsCaller 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 {
// 通过反射调用main函数
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);
}
}
}

从上面的分析中可以看到,system_server进程创建后,会通过反射创建"com.android.server.SystemServer"入口类对象并执行其main方法,我们继续往下看代码简化流程:

/frameworks/base/services/java/com/android/server/SystemServer.java/
public static void main(String[] args) {
new SystemServer().run();
}

private void run() {

// 1.创建主线程Looper
Looper.prepareMainLooper();
// 2.创建系统Context上下文
createSystemContext();
// 3.创建SystemServiceManager,用于后续系统服务(AMS、WMS等)的创建、启动和生命周期管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// 4.服务根据优先级被分成3批来启动:
try {
t.traceBegin(“StartServices”);
//启动引导服务,如AMS、PMS等
startBootstrapServices(t);
//启动核心服务
startCoreServices(t);
//启动其他服务
startOtherServices(t);
} catch (Throwable ex) {
Slog.e(“System”, “******************************");
Slog.e(“System”, "
Failure starting system services”, ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
// 5.开启looper循环
Looper.loop();
}

总结一下上述流程,system_server进程创建之后,主要做了如下几件事情

  1. 启动进程的Binder线程池;

  2. 创建SystemServiceManager大管家,用于后续系统服务(AMS、WMS等)的创建、启动和生命周期管理;

  3. 用SystemServiceManager按照优先级启动系统各个服务;

  4. 创建并启动进程的主线程的loop循环;

4. Launcher应用的启动

我们接上一节system_server进程创建之后启动系统服务的流程往下看,以AMS服务的启动为例,相关简化代码流程如下:

/frameworks/base/services/java/com/android/server/SystemServer.java/
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {

t.traceBegin(“StartActivityManager”);
// 1.SystemServiceManager启动AMS服务
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
t.traceEnd();

}

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {

// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
// 2.从这里开始便可以开始启动三方APP应用(如Launcher)
mActivityManagerService.systemReady(() -> {

}, t);
}

从上面的代码流程中可以看到system_server进程创建之后,启动系统各核心服务的最后会调用到mActivityManagerService#systemReady便可正式开始启动三方APP应用(如Launcher),我们继续往下看:

/frameworks/base/services/java/com/android/server/am/ActivitymanagerService.java/
public void systemReady(final Runnable goingCallback, TimingsTraceAndSlog t){

if (bootingSystemUser) {
t.traceBegin(“startHomeOnAllDisplays”);
// 由于Android系统支持多用户和多显示,调用startHomeOnAllDisplays启动每个display上的Home Activity
mAtmInternal.startHomeOnAllDisplays(currentUserId,“systemReady”);
t.traceEnd();
}
}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

以上分享【我的阿里P7移动开发架构师学习笔记】七大模块整套学习资料均免费分享,需要的小伙伴,我已经上传到石墨文档了,大家自取就可以了。白嫖可以,别忘了给我点个关注哈。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

如果你需要,我把他放在GitHub了,无偿分享的。

【Android架构视频+BATJ面试专题PDF+学习笔记】

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

如果你需要,我把他放在GitHub了,无偿分享的。

【Android架构视频+BATJ面试专题PDF+学习笔记】

[外链图片转存中…(img-pDzIZahN-1711170956245)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值