SystemServer分析之启动服务

2024-09-05 22:18

本文主要是介绍SystemServer分析之启动服务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 涉及的代码

  • frameworks\base\services\java\com\android\server\SystemServer.java
  • frameworks\base\core\java\android\app\ActivityThread.java
  • rameworks\base\core\java\android\app\ContextImpl.java
  • frameworks\base\services\core\java\com\android\server\SystemServiceManager.java
  • frameworks\base\core\java\com\android\server\LocalServices.java

SystemServer中ActivityManagerService调用图

这里写图片描述

代码分析

SystemServer的main

初始化环境

//此时会去执行run方法new SystemServer().run();

run方法将会对整个系统的Service做初始化,在搭建完运行时环境和上下完后
依次创建消息队列 、加载native lib 库,并进行native的初始化

Looper.prepareMainLooper();
System.loadLibrary("android_servers");
nativeInit();

初始化系统上下文

初始化上下文围绕着activityThread来进行

 createSystemContext();

下边来看一下这个初始化上下文的过程

ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
SystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);

首先会调用 ActivityThread的静态方法systemMain,得到一个ActivityThread对象,systemMain是获取资源的instance。
需要注意的是ActivityThread中虽然含有Thread,然而其却不是线程。

创建系统服务管理者

// Create the system service manager.mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

首先会实例化一个SystemServiceManager对象,并将这个实例化的对象添加到LocalService中。

public SystemServiceManager(Context context) {mContext = context;
}

实例化SystemServiceManager的过程就是系统的上下文对象传入到SystemServiceManager这个类里边。 后续再启动service的实话,会使用这个mContext创建出service。

service = constructor.newInstance(mContext);
本地服务的添加

本地服务实际上是使用ArrayMap,通过键值对的实行来存放的。
LocalService.java中定义了

private static final ArrayMap<Class<?>, Object> sLocalServiceObjects = new ArrayMap<Class<?>, Object>();

来存放服务。 sLoaclServiceObject是一个ArrayMap类型的static属性。

    public static <T> void addService(Class<T> type, T service) {synchronized (sLocalServiceObjects) {if (sLocalServiceObjects.containsKey(type)) {throw new IllegalStateException("Overriding service registration");}sLocalServiceObjects.put(type, service);}}

添加过程就是将Class类型的type和 service添加到其中

  public static <T> T getService(Class<T> type) {synchronized (sLocalServiceObjects) {return (T) sLocalServiceObjects.get(type);}}

获取的过程,能通过Class名,来获得相应的service。

在需要使用SystemServiceManager的service的时候,就可以通过LocalService.getService(SystemServiceManager.class)来得到这个service
此时的mSystemServiceManager仅仅是创建是创建出来,并没有运行。

startBootstrapServices

在这个方法中,主要是调用mSystemServiceManager的startService方法启动一些服务
startService方法有两个,分别是

  public SystemService startService(String className)public <T extends SystemService> T startService(Class<T> serviceClass) 

第一种方法是通过string类型的字符串来查找。第二种方法是通过Class类查找。
实际上第一种方法,依然是调用第二种方法。

 public SystemService startService(String className)final Class<SystemService> serviceClass;serviceClass = (Class<SystemService>)Class.forName(className)return startService(serviceClass)

这里运用反射 Class.forName创建一个对象

  public <T extends SystemService> T startService(Class<T> serviceClass) {final String name = serviceClass.getName();Constructor<T> constructor = serviceClass.getConstructor(Context.class);//实例化对象serviceservice = constructor.newInstance(mContext);//将这个service添加到 new ArrayList<SystemService>中mServices.add(service);//启动这个serviceservice.onStart();return service;

mSystemServiceManager通过startService利用反射,启动了Installer、ActivityManagerService、PowerManagerService、DisplayManagerService服务

这篇关于SystemServer分析之启动服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140217

相关文章

nginx启动命令和默认配置文件的使用

《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

Nexus安装和启动的实现教程

《Nexus安装和启动的实现教程》:本文主要介绍Nexus安装和启动的实现教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Nexus下载二、Nexus安装和启动三、关闭Nexus总结一、Nexus下载官方下载链接:DownloadWindows系统根

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意