Android Framework学习笔记(三)SystemServer进程启动过程

回到RuntimeInit#zygoteInit()的注释2。

RuntimeInit#applicationInit()

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

throws ZygoteInit.MethodAndArgsCaller {

// 初始化虚拟机环境

VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);

VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

final Arguments args;

try {

args = new Arguments(argv);

} catch (IllegalArgumentException ex) {

Slog.e(TAG, ex.getMessage());

// let the process exit

return;

}

// Remaining arguments are passed to the start class’s static main

invokeStaticMain(args.startClass, args.startArgs, classLoader); //1

}

注释1处applicationInit函数中主要调用了invokeStaticMain函数。

RuntimeInit#invokeStaticMain()

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {

Class<?> cl;

try {

cl = Class.forName(className, true, classLoader); //1

} catch (ClassNotFoundException ex) {

throw new RuntimeException("Missing class when invoking static main " + className, ex);

}

Method m;

try {

// 获取main方法

m = cl.getMethod(“main”, new Class[] { String[].class }); //2

} 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);

}

// 判断修饰符

int modifiers = m.getModifiers(); //3

if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {

throw new RuntimeException("Main method is not public and static on " + className);

}

/*

  • 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.

*/

throw new ZygoteInit.MethodAndArgsCaller(m, argv); //4

}

注释1处传入的className就是com.android.server.SystemServer ,因此通过反射返回的cl为SystemServer类。

注释2获取main方法 。

注释3判断修饰符,必须是static而且必须是public类型。

注释4有点意思,做完这一切之后,将找到的main函数传入到MethodAndArgsCaller异常中并抛出该异常。辛苦辛苦各种初始化,各种变着法的调用,最后你居然给我抛个异常!先别急,这个异常在ZygoteInit#main()方法中捕获。这么做的作用是清除应用程序进程创建过程的调用栈。

ZygoteInit#main()函数见上一篇文章,我们这里再看一下框架:

public static void main(String argv[]) {

try {

startSystemServer(abiList, socketName);

} catch (MethodAndArgsCaller caller) {

caller.run(); //1

}

}

在注释1处调用了MethodAndArgsCaller的run函数。

MethodAndArgsCaller

public static class MethodAndArgsCaller extends Exception

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 {

mMethod.invoke(null, new Object[] { mArgs }); //1

} 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);

}

}

}

注释1处通过反射调用了com.android.server.SystemServer#main(String[] args)。至此,Zygote进程fork出SystemServer进程,并成功调用SystemServer#main()。

解析SyetemServer进程

我们先来查看SystemServer的main函数:

frameworks/base/services/java/com/android/server/SystemServer.java

SystemServer#main()

public static void main(String[] args) {

new SystemServer().run(); //1

}

注释1处main函数中只调用了SystemServer的run函数。

SystemServer#run()

private void run() {

System.loadLibrary(“android_servers”);//1

mSystemServiceManager = new SystemServiceManager(mSystemContext);//2

LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

try {

Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, “StartServices”);

startBootstrapServices();//3

startCoreServices();//4

startOtherServices();//5

} catch (Throwable ex) {

Slog.e(“System”, “******************************************”);

Slog.e(“System”, “************ Failure starting system services”, ex);

throw ex;

} finally {

Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

}

}

注释1处加载了libandroid_servers.so。

注释2处创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。启动系统的各种服务。

注释3中的startBootstrapServices函数中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。

注释4处的函数中则启动了BatteryService、UsageStatsService和WebViewUpdateService。

注释5处的startOtherServices函数中则启动了CameraService、AlarmManagerService、VrManagerService等服务,这些服务的父类为SystemService。

从注释3、4、5的函数可以看出,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务为一些非紧要和一些不需要立即启动的服务。系统服务大约有80多个,这里列出部分系统服务以及它们的作用:

image

image

image

继续往下看,我们这里只看看注释3如何启动引导服务,注释4、5类似。

SystemServer#startBootstrapServices()

private void startBootstrapServices() {

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

}

这里面要启动的引导服务很多,我们来看看PowerManagerService和PackageManagerService吧。

首先是PowerManagerService,它是通过SystemServiceManager.startService()来启动的:

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

SystemServiceManager#startService()

public T startService(Class serviceClass) {

try {

final String name = serviceClass.getName();

final T service;

try {

Constructor constructor = serviceClass.getConstructor(Context.class);

service = constructor.newInstance(mContext); //1

} catch (InstantiationException ex) {

throw new RuntimeException("Failed to create service " + name + “: service could not be instantiated”, ex);

} catch (IllegalAccessException ex) {

throw new RuntimeException("Failed to create service " + name + “: service must have a public constructor with a Context argument”, ex);

} catch (NoSuchMethodException ex) {

throw new RuntimeException("Failed to create service " + name + “: service must have a public constructor with a Context argument”, ex);

} catch (InvocationTargetException ex) {

throw new RuntimeException("Failed to create service " + name + “: service constructor threw an exception”, ex);

}

// Register it.

mServices.add(service); //2

// Start it.

try {

service.onStart(); //3

} catch (RuntimeException ex) {

throw new RuntimeException("Failed to start service " + name + “: onStart threw an exception”, ex);

}

return service;

} finally {

Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

}

}

注释1处通过构造器创建SystemService,这里的SystemService就是PowerManagerService。

注释2处将PowerManagerService添加到mServices中,这里mServices是一个存储SystemService类型的ArrayList。

注释3处接着调用PowerManagerService的onStart函数启动PowerManagerService并返回,这样就完成了PowerManagerService启动的过程。

接下来再来看看PackageManagerService,它是通过另外一种方式启动的,直接调用了PackageManagerService的main函数:

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

PackageManagerService#main()

public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) {

// Self-check for initial settings.

PackageManagerServiceCompilerMapping.checkProperties();

PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); //1

m.enableSystemUserPackages();

// Disable any carrier apps. We do this very early in boot to prevent the apps from being

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

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

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

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

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

技术进阶之路很漫长,一起共勉吧~

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

,包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-WZMcVRcx-1712097554549)]

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

技术进阶之路很漫长,一起共勉吧~

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值