征服Android面试官路漫漫(四):5 张图带你搞懂Android系统启动的核心流程

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

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

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

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

return;

}

//2. 为java虚拟机注册JNI方法

if (startReg(env) < 0) {

return;

}

//根据传入的参数找到ZygoteInit类和他的main函数

//3. 通过JNI调用ZygoteInit的main函数

env->CallStaticVoidMethod(startClass, startMeth, strArray);

}

Java层ZygoteInit

来到ZygoteInit的main函数,

//ZygoteInit.java

public static void main(String argv[]) {

//是否要创建SystemServer

boolean startSystemServer = false;

//默认的socket名字

String socketName = “zygote”;

//是否要延迟资源的预加载

boolean enableLazyPreload = false;

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])) {

//init.rc没有这个参数,资源的预加载不会被延迟

enableLazyPreload = true;

} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {

//init.rc可以通过–socket-name=指定socket名字来覆盖默认值

socketName = argv[i].substring(SOCKET_NAME_ARG.length());

}

}

//1. 创建服务端socket,名字为socketName即zygote

zygoteServer.registerServerSocket(socketName);

if (!enableLazyPreload) {

//2. 没有被延迟,就预加载资源

preload(bootTimingsTraceLog);

}

if (startSystemServer) {

//3. fork并启动SystemServer进程

startSystemServer(abiList, socketName, zygoteServer);

}

//4. 等待AMS请求(AMS会通过socket请求Zygote来创建应用程序进程)

zygoteServer.runSelectLoop(abiList);

}

总结一下native层的3个环节和Java层的4个环节:

SystemServer启动


SystemServer进程主要负责创建启动系统服务如AMS、WMS和PMS等

从前边可知SystemServer进程由Zygote进程fork出来并启动,在ZygoteInit类中,

//ZygoteInit.java

private static boolean startSystemServer(…){

String args[] = {

//…

//启动的类名:

“com.android.server.SystemServer”,

};

//fork进程,由native层实现

pid = Zygote.forkSystemServer();

//处理SystemServer进程

handleSystemServerProcess(parsedArgs);

}

private static void handleSystemServerProcess(…){

ZygoteInit.zygoteInit(…);

}

public static final void zygoteInit(…){

//启动binder线程池

ZygoteInit.nativeZygoteInit();

//内部经过层层调用,找到"com.android.server.SystemServer"类和他的main函数,然后执行

RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);

}

这里启动了binder线程池,SystemServer进程就可以用binder机制来跨进程通信了(Zygote进程是用socket来通信的),接着进入了SystemServer的main函数,

//SystemServer.java

public static void main(String[] args) {

new SystemServer().run();

}

private void run() {

//创建looper

Looper.prepareMainLooper();

//加载动态库libandroid_servers.so

System.loadLibrary(“android_servers”);

//创建系统上下文

createSystemContext();

//创建SSM,用于服务的创建、启动和生命周期管理

mSystemServiceManager = new SystemServiceManager(mSystemContext);

//服务根据优先级被分成3批来启动:

//启动引导服务,如AMS、PMS等

startBootstrapServices();

//启动核心服务

startCoreServices();

//启动其他服务

startOtherServices();

//开启looper循环

Looper.loop();

}

看下AMS的启动,

//SystemServer.java

private void startBootstrapServices() {

//由SSM创建启动

mActivityManagerService = mSystemServiceManager.startService(

ActivityManagerService.Lifecycle.class).getService();

mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

}

private void startOtherServices() {

//AMS准备就绪

mActivityManagerService.systemReady(…);

}

总结一下,SystemServer进程被创建后,主要做了3件事情:启动binder线程池、创建SystemServiceManager(SSM)、用SSM启动各种服务

Launcher的启动


Launcher作为Android的桌面,用于管理应用图标和桌面组件

前边可知SystemServer进程会启动各种服务,其中PackageManagerService启动后会将系统中的应用程序安装完成,然后由AMS来启动Launcher。

//SystemServer.java

private void startOtherServices() {

//AMS准备就绪

mActivityManagerService.systemReady(…);

}

跟进ActivityManagerService,

//ActivityManagerService.java

public void systemReady(…) {

//经过层层调用来到startHomeActivityLocked

}

boolean startHomeActivityLocked(…) {

//最终会启动Launcher应用的Activity

mActivityStarter.startHomeActivityLocked(…);

}

Activity类是Launcher.java,剩下的流程就是加载已安装的应用程序信息,然后展示,就不具体分析了。

总结

Android系统启动的核心流程如下:

  1. Linux内核启动

  2. init进程启动

  3. init进程fork出Zygote进程

  4. Zygote进程fork出SystemServer进程

  5. SystemServer进程启动各项服务(PMS、AMS等)

  6. AMS服务启动Launcher桌面

Zygote进程启动好服务端socket后,便会等待AMS的socket请求,来创建应用程序进程。

细节补充


  • Zygote的跨进程通信没有使用binder,而是socket,所以应用程序进程的binder机制不是继承而来,而是进程创建后自己启动的。

  • Zygote跨进程通信之所以用socket而不是binder,是因为binder通信是多线程的,而Zygote需要在单线程状态下fork子进程来避免死锁问题。

  • PMS、AMS等系统服务启动后会调用ServiceManager.addService()注册,然后运行在自己的工作线程。

如何进阶Android?

有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

最后

题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

Android开发8年,阿里、百度一面惨被吊打!我是否应该转行了?

【Android进阶学习视频】、【全套Android面试秘籍】

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-ktrUi1uv-1713331312104)]

【Android进阶学习视频】、【全套Android面试秘籍】

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-rhuviiCS-1713331312105)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值