android的system_server进程的启动

news/2024/5/15 2:16:50/文章来源:https://blog.csdn.net/weixin_43228946/article/details/129898004

android的system_server进程的启动

android的system_server进程的启动的简单介绍

system_server是Zygote的fork的第一个Java进程相当于它的大儿子,这个进程非常重要的,这里这个进程提供了很多系统线程,提供了所有的核心的系统服务。比如,WindowManager,ActivityManager等,这些都是运行在system_server的进程里。还有很多“Binder-x"的线程,这些线程是各个服Service为了响应应用程序远程调用请求而创建的。除此之外,还有很多内部线程,比如”UI thread“,”InputReader","InputDispatch"等等。我们要了解system_server创建和启动流程

new SystemServer().run();

(源码地址:http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/java/com/android/server/SystemServer.java)

 public static void main(String[] args) {new SystemServer().run();}private void run() {。。。。。
}

这里需要注意一下由于这个run比较长,可以到网址里去看,是在第307行。

run()

在run()主要是做了一些初始化工作,现在我们来看看初始化的:
(1)初始化必要的SystemServer环境参数,比如系统时间,默认时区,语言,load一些Library等等,
(2)初始化Looper,在主线程中使用的looper就是在SystemServer进行初始化,
(3)初始化Context,只有初始化一个Context才能启动Service的操作。
在这里插入图片描述

 private void createSystemContext() {
522        ActivityThread activityThread = ActivityThread.systemMain();
523        mSystemContext = activityThread.getSystemContext();
524        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
525
526        final Context systemUiContext = activityThread.getSystemUiContext();
527        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
528    }

在这里我们以清楚看看到ActivityThread就是在这里初始化的,也可以看到ActivityThread是如何生成的SystemContext系统上下文的,主要是通过ActivityThread里的getSystemContext()生成的。
其对应的代码的位置:http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.java

    public ContextImpl getSystemContext() {synchronized (this) {if (mSystemContext == null) {mSystemContext = ContextImpl.createSystemContext(this);}return mSystemContext;}}

ContextImpl是Context类的具体实现,里面封装完成了生成几种常用的createContext的方法:
代码位置:http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ContextImpl.java

2318    static ContextImpl createSystemContext(ActivityThread mainThread) {
2319        LoadedApk packageInfo = new LoadedApk(mainThread);
2320        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
2321                null);
2322        context.setResources(packageInfo.getResources());
2323        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
2324                context.mResourcesManager.getDisplayMetrics());
2325        return context;
2326    }
2327
2328    /**
2329     * System Context to be used for UI. This Context has resources that can be themed.
2330     * Make sure that the created system UI context shares the same LoadedApk as the system context.
2331     */
2332    static ContextImpl createSystemUiContext(ContextImpl systemContext) {
2333        final LoadedApk packageInfo = systemContext.mPackageInfo;
2334        ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null,
2335                null, null, 0, null);
2336        context.setResources(createResources(null, packageInfo, null, Display.DEFAULT_DISPLAY, null,
2337                packageInfo.getCompatibilityInfo()));
2338        return context;
2339    }
2340
2341    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
2342        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
2343        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
2344                null);
2345        context.setResources(packageInfo.getResources());
2346        return context;
2347    }
2348
2349    static ContextImpl createActivityContext(ActivityThread mainThread,
2350            LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
2351            Configuration overrideConfiguration) {
2352        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
2353
2354        String[] splitDirs = packageInfo.getSplitResDirs();
2355        ClassLoader classLoader = packageInfo.getClassLoader();
2356
2357        if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
2358            Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies");
2359            try {
2360                classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName);
2361                splitDirs = packageInfo.getSplitPaths(activityInfo.splitName);
2362            } catch (NameNotFoundException e) {
2363                // Nothing above us can handle a NameNotFoundException, better crash.
2364                throw new RuntimeException(e);
2365            } finally {
2366                Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
2367            }
2368        }
2369
2370        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
2371                activityToken, null, 0, classLoader);
2372
2373        // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
2374        displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
2375
2376        final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
2377                ? packageInfo.getCompatibilityInfo()
2378                : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
2379
2380        final ResourcesManager resourcesManager = ResourcesManager.getInstance();
2381
2382        // Create the base resources for which all configuration contexts for this Activity
2383        // will be rebased upon.
2384        context.setResources(resourcesManager.createBaseActivityResources(activityToken,
2385                packageInfo.getResDir(),
2386                splitDirs,
2387                packageInfo.getOverlayDirs(),
2388                packageInfo.getApplicationInfo().sharedLibraryFiles,
2389                displayId,
2390                overrideConfiguration,
2391                compatInfo,
2392                classLoader));
2393        context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
2394                context.getResources());
2395        return context;
2396    }

接着是初始化SystemServiceManager,,这个主要是为了用来管理启动service,SystemServiceManager中封装了启动Service的,所以为了,可以看看startService方法,启动系统必要的Service,代码位置如下:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/java/com/android/server/SystemServer.java

// Start services.
427        try {
428            traceBeginAndSlog("StartServices");
429            startBootstrapServices();
430            startCoreServices();
431            startOtherServices();
432            SystemServerInitThreadPool.shutdown();
433        } catch (Throwable ex) {
434            Slog.e("System", "******************************************");
435            Slog.e("System", "************ Failure starting system services", ex);
436            throw ex;
437        } finally {
438            traceEnd();
439        }

在这里可以很明显看到startBootstrapServices(),startCoreServices(),startOtherServices(),这里三个方法启动了很多Android服务,现在我们分别介绍一下,这三个方法:
startBootstrapServices():是Android系统中SystemServer.java类中的一个方法,用于启动系统启动时必要的服务。
在这里插入图片描述
startBootstrapServices()方法会在系统启动时被调用,以确保这些服务在系统其他部分调用它们之前就已经启动并正常运行。
startCoreServices():是Android系统中SystemServer.java类中的一个方法,用于启动系统的核心服务。
在这里插入图片描述
startOtherServices():是Android系统中SystemServer.java类中的一个方法,用于启动系统的其他服务。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后一个服务,不再贴图片,直接上文字:
RetailDemoModeService是Android系统中的一个服务,用于在零售演示模式下控制设备的行为。该服务主要用于在零售店等场合展示Android设备的功能和应用程序,以便吸引用户购买。
RetailDemoModeService服务在系统启动时自动启动,其主要作用包括:
控制设备的屏幕亮度、音量、循环播放视频等。
配置设备的网络连接,以便在演示时展示网络功能。
配置应用程序的布局和内容,以便在演示时展示应用程序功能。
监听设备的按键事件和触摸事件,以便在演示时进行交互操作。
提供API供应用程序调用,以便在演示时控制设备的行为。
该服务仅适用于特定的设备和场合,一般用户无需关心或使用该服务。
(备注:参考的博客:https://www.jianshu.com/p/9912a556734f)

最后Zygote的善后工作

代码位置:dalvik/vm/native/dalvik_system_zygote.cpp
Zygote监视system_server进程,一旦发现SystemServer 挂掉了,将其回收,然后将自己杀掉,重新开始。

static void Dalvik_dalvik_system_Zygote_forkSystemServer(
2 const u4* args, JValue* pResult){ 3 ... 4 pid_t pid;
5 pid = forkAndSpecializeCommon(args, true); 6 ... 7 if (pid > 0) {
8 int status;
9 gDvm.systemServerPid = pid;
10 /* WNOHANG 会让waitpid 立即返回,这里只是为了预防上面的赋值语句没有完成之前
SystemServer就crash 了*/
11 if (waitpid(pid, &status, WNOHANG) == pid) {
12 ALOGE("System server process %d has died. Restarting Zygote!",
pid);
13 kill(getpid(), SIGKILL); 14
}
15 }
16 RETURN_INT(pid); 17
}
18
19 /* 真正的处理在这里 */
20 static void sigchldHandler(int s){ 21
... 22 pid_t pid;
23 int status;
24 ...
25 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 26
...
27 if (pid == gDvm.systemServerPid) { 28
...
29 kill(getpid(), SIGKILL); 30
}
31 }
32 ...
33 }
34
35 static void Dalvik_dalvik_system_Zygote_fork(const u4* args, JValue* pResult){
36 pid_t pid;
37 ...
38 setSignalHandler(); //signalHandler 在这里注册
39 ...
40 pid = fork();
41 ...
42 RETURN_INT(pid);
1 pid_t fork(void)
43 }

在Unix-like系统,父进程必须用 waitpid 等待子进程的退出,否则子进程将变成”
Zombie” (僵尸)进
程,不仅系统资源泄漏,而且系统将崩溃(没有system server,所有Android应用程序都无法运行)。
但是waitpid() 是一个阻塞函数(WNOHANG参数除外),所以通常做法是在signal 处理函数里进行无阻
塞的处理,因为每个子进程退出的时候,系统会发出 SIGCHID 信号。Zygote会把自己杀掉, 那父亲死
了,所有的应用程序不就成为孤儿了? 不会,因为父进程被杀掉后系统会自动给所有的子进程发生
SIGHUP信号,该信号的默认处理就是将杀掉自己退出当前进程。但是一些后台进程(Daemon)可以通 过设
置SIG_IGN参数来忽略这个信号,从而得以在后台继续运行。

总结

  1. init 根据init.rc 运行 app_process, 并携带‘–zygote’ 和 ’–startSystemServer’ 参
    数。
  2. AndroidRuntime.cpp::start() 里将启动JavaVM,并且注册所有framework相关的系统JNI接口。
  3. 第一次进入Java世界,运行ZygoteInit.java::main() 函数初始化Zygote. Zygote 并创建Socket

    server 端。
  4. 然后fork一个新的进程并在新进程里初始化SystemServer. Fork之前,Zygote是preload常用的
    Java类库,以及系统的resources,同时GC()清理内存空间,为子进程省去重复的工作。
  5. SystemServer 里将所有的系统Service初始化,包括ActivityManager 和 WindowManager, 他们
    是应用程序运行起来的前提。
  6. 依次同时,Zygote监听服务端Socket,等待新的应用启动请求。
  7. ActivityManager ready 之后寻找系统的“Startup” Application, 将请求发给Zygote。
  8. Zygote收到请求后,fork出一个新的进程。
  9. Zygote监听并处理SystemServer 的 SIGCHID 信号,一旦System Server崩溃,立即将自己杀死。
    init会重启Zygote
    (这里参考了相关问答)

在Android 10中,Dalvik已经被ART所取代,因此没有dalvik_system_zygote.cpp文件了。如果您需要查看ART的系统进程启动代码,可以参考art/runtime/runtime.cc文件中的Runtime::Start函数。这个函数是ART的入口点之一,负责启动ART虚拟机,并初始化系统进程和应用程序进程。

在Android 10中,ART的实现代码位于art/runtime目录下。其中,art/runtime/entrypoints目录下的文件包含了ART的入口点代码,art/runtime/gc目录下的文件包含了ART的垃圾回收器实现代码,art/runtime/interpreter目录下的文件包含了ART的解释器实现代码,art/runtime/mirror目录下的文件包含了ART的对象模型实现代码。如果您需要查看ART的具体实现细节,可以参考这些目录下的文件。

Android 10中的ART和之前的Dalvik相比有三个主要变化:

从JIT(Just-In-Time)编译器到AOT编译器
在Dalvik中,应用程序的字节码是在运行时通过JIT编译器动态地转换为本地代码,这会导致应用程序启动时的延迟。而在ART中,应用程序的字节码在安装时就全部编译为本地代码,这样应用程序的启动速度大大提高。

优化的垃圾回收器
ART中使用了一种新的垃圾回收器,称为CC(Concurrent Compact)垃圾回收器。这种垃圾回收器可以在不影响应用程序性能的情况下,对内存进行高效的回收和整理。相比之下,Dalvik中的垃圾回收器是基于标记-清除算法的,效率较低。

更好的性能和稳定性
ART将应用程序的字节码预先编译为本地代码,因此在应用程序运行时不再需要进行JIT编译,这样可以提高性能。此外,ART还采用了一些新的技术,如栈上分配、类初始化和方法内联等,来进一步提高应用程序的性能和稳定性。

总之,Android 10中的ART相比Dalvik有着更好的性能和稳定性,并且能够更快地启动应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283208.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql与redis区别

一、.redis和mysql的区别总结 (1)类型上 从类型上来说,mysql是关系型数据库,redis是缓存数据库 (2)作用上 mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢 redis用于存储使…

SQL基础查选和条件查选

写完毕业论文,终于有空复习sql了,继续学习之旅~下次不能和上次一样,简单的sql语句都忘记了。 1.查询结果去重 关键字 distinct select distinct university from user_profile; 2. 将查询后的列重新命名 关键字 as 关键字limit…

Linux kernel 编译 exfat.ko ntfs.ko 来支持exFat 和 NTFS 分区

项目需求想让设备支持 exFat 和 NTFS 的文件格式. 默认的内核是不支持的,因为内核要限定1.5M之内, 所以很多东西都裁剪掉了. 而且不是所有项目都有这个需求,所以就需要编译为 ko ,按需加载; 而不是才去built-in的方式. 在如下的选项找到对应的配置. 至于如何找到, 我推荐2种方式…

LE AUDIO快速了解

有BIS和CIS两种 BIS是广播的,不需要连接,只需要监听 CIS要建立连接的,除了ACL链路,还需要建立CIS链路 BIS部分 也没啥要看的,只需要记住3个指令就可以了 主要是HCI的3个指令 2068 206b 206e 这3个指令即可 206…

Nacos安全性探究

Nacos怎么做安全校验的? 以下使用nacos2.x 如上图所示, 可以直接访问Nacos的接口来获取用户列表。这说明Nacos的接口被爆露,任何情况下都可以访问,因此安全性得不到保障。 Nacos 使用 spring security 作为安全框架。spring sec…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK获取每张图像的微秒时间和FrameID(C#)

BGAPI SDK获取图像微秒级时间和FrameID Baumer工业相机Baumer工业相机FrameID技术背景一、FrameID是什么?二、使用BGAPI SDK获取图像微秒时间和FrameID步骤 1.获取SDK图像微秒级时间2.获取SDK图像FrameIDBaumer工业相机使用微秒级时间和FrameID保存的用处Baumer工业…

混淆矩阵Confusion Matrix(resnet34 基于 CIFAR10)

目录 1. Confusion Matrix 2. 其他的性能指标 3. example 4. 代码实现混淆矩阵 5. 测试,计算混淆矩阵 6. show 7. 代码 1. Confusion Matrix 混淆矩阵可以将真实标签和预测标签的结果以矩阵的形式表示出来,相比于之前计算的正确率acc更加的直观…

jenkins打包发布前端项目

1.配置前端nodejs打包环境 1.1安装nodejs插件 1.2配置jenkins nodejs环境 2.下载git插件(使用此插件配置通过gitlab标签拉取项目) 3.创建一个自由风格的发布项目 4.配置项目构建流程 4.1添加钉钉告警 4.2配置参数化构建 4.3配置源码管理为git拉取项目 4.4配置构建环境 4.5配置…

transform属性

CSS transform属性允许对某一个元素进行某些形变, 包括旋转,缩放,倾斜或平移等。 注意事项,并非所有的盒子都可以进行transform的转换,transform对于行内级非替换元素是无效的,比如对span、a元素等 常见的函数transform function有&#xf…

算法笔记:匈牙利算法

1 二部图(二分图) 二分图(Bipartite graph)是一类特殊的图,它可以被划分为两个部分,每个部分内的点互不相连。 匈牙利算法主要用来解决两个问题:求二分图的最大匹配数和最小点覆盖数。 2 最大匹…

[C++笔记]初步了解STL,string,迭代器

STL简介 STL(standard template libaray-标准模板库): 是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包含数据结构与算法的软件框架。 是一套功能强大的 C 模板类,提供了通用的模板类和函数,这些模板…

STM32开发(十二)STM32F103 功能应用 —— NTC 温度采集

文章目录一、基础知识点二、开发环境三、STM32CubeMX相关配置四、Vscode代码讲解(过程中相关问题点在第五点中做解释说明)五、知识点补充六、结果演示一、基础知识点 了解STM32 片内资源ADC。本实验是基于STM32F103开发 实现 NTC温度采集。 NTC温度采集…

3年外包离奇被裁,痛定思痛24K上岸字节跳动....

三年前,我刚刚从大学毕业,来到了一家外包公司工作。这份工作对于我来说是个好的起点,因为它让我接触到了真正的企业项目和实际的开发流程。但是,随着时间的流逝,我发现这份工作并没有给我带来足够的成长和挑战。 三年…

文心一言平替版ChatGLM本地部署(无需账号)!

今天用了一个超级好用的Chatgpt模型——ChatGLM,可以很方便的本地部署,而且效果嘎嘎好,经测试,效果基本可以平替内测版的文心一言。 目录 一、什么是ChatGLM? 二、本地部署 2.1 模型下载 2.2 模型部署 2.3 模型运…

数据结构系列13——排序(归并排序)

目录 1. 递归实现归并排序 1.1 思路 1.2 代码实现 1.3 时间复杂度和空间复杂度 2. 非递归实现归并排序 2.1 思路 2.2 代码实现 2.3 时间复杂度和空间复杂度 1. 递归实现归并排序 1.1 思路 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列…

Excel 文件 - 比如 .csv文件编码问题 转为 UTF-8 编码 方法,解决中文乱码问题 - 解决科学计数显示问题

解决 excel 文件编码问题 1、方法一: 有点点击 excel 文件,然后选择打开方式,选择使用 Excel 2016 软件打开 选择 工具 ——> Web 选项 这里选择 UTF-8 编码 2、方法二 wps 导出为 .csv 文件,然后修改 csv 文件的后缀…

Linux修改密码报错Authentication token manipulation error的终极解决方法

文章目录报错说明解决思路流程排查特殊权限有没有上锁查看根目录和关闭selinux/etc/pam.d/passwd文件/etc/pam.d/system-auth文件终极办法,手动定义密码passwd: Have exhausted maximum number of retries for servic、ssh用普通用户登录输入密码正确但是登录时却提…

元宇宙是什么,元宇宙虚拟会议改变会议体验

随着人类社会的发展和科技的进步,传统的会议方式已经无法满足现代社会的需求。为了更好地满足社会的需求,VR全景元宇宙虚拟会议是近年来快速崛起的新兴领域,其融合了虚拟现实技术和通信技术,为人们提供了一种全新的交流、协作和学…

【探花交友】day02—完善个人信息

目录 1、完善用户信息 1.1、阿里云OSS 1.2、百度人脸识别 1.3、保存用户信息 1.4、上传用户头像 2、用户信息管理 2.1、查询用户资料 2.2、更新用户资料 3、统一token处理 3.1、代码存在的问题 3.2、解决方案 3.3、代码实现 4、统一异常处理 4.1、解决方案 4.2、…

本地部署Stable Diffusion教程,亲测可以安装成功

系列文章目录 之后补充 文章目录系列文章目录前言一、Stable Diffusion是什么?二、安装前的准备1.检查自己的电脑配置是否符合要求2.下载安装Git3.下载安装Python三、下载stable-diffusion-webui仓库四、运行webui-user.bat总结前言 近期,智能AI绘画以其…