SystemServer的启动之一

Android  源码分析  2023年8月15日 am8:08发布1年前 (2023)更新 城堡大人
153 0 0

前言

之前介绍过Zygote的启动流程,然后这里会forkSystemServer(),然后通过一系列最终找到SystemServer的main函数入口。

今天就进入看看SystemServer.java中干了啥。

PS: 这里只是走走流程,细节暂不分析

涉及文件

frameworks\base\services\java\com\android\server\SystemServer.java
frameworks\base\services\core\jni\com_android_server_SystemServer.cpp

正文

从《Zygote的启动之二ZygoteInit》可以知道

Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    handleSystemServerProcess()
     zygoteInit()
      RuntimeInit.applicationInit()
       findStaticMain()
        new MethodAndArgsCaller()
r.run();

findStaticMain()就是找com.android.server.SystemServer中的main(),因此,我们进入了SystemServer.java的main()。

直入main()

main()

public static void main(String[] args) {
    //匿名创建SystemServer对象,并调用run()
    new SystemServer().run();
}

run()

这里主要做了如下工作。

  1. 初始化环境,比如时间,时区,语言等

  2. 准备主线程Looper

  3. 加载libandroid_servers.so库

  4. 初始化系统Context

  5. 创建SystemServiceManager

  6. 启动服务(引导服务核心服务,其他服务)

  7. 进入Looper循环

private void run() {
    try {
        //获取当前时间,如果小于最早支持时间1970,就设置为1970
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
        //设置系统时区:GMT
        String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
        if (timezoneProperty == null || timezoneProperty.isEmpty()) {
            SystemProperties.set("persist.sys.timezone", "GMT");
        }
        //设置系统默认语言和环境等
        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();
            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language", "");
            SystemProperties.set("persist.sys.country", "");
            SystemProperties.set("persist.sys.localevar", "");
        }
        //略
        //设置当前虚拟机的运行库路径
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
        // Mmmmmm... more memory!
        VMRuntime.getRuntime().clearGrowthLimit();
        //设置虚拟机堆内存
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
        //略
        //设置做大的线程数
        BinderInternal.setMaxThreads(sMaxBinderThreads);
        //设置线程优先级
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        //初始化主线程Looper
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
        //加载libandroid_servers.so库
        SystemServerInitThreadPool.get().submit(() -> {
            System.loadLibrary("android_servers");
        }, "android_servers");
        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        //检测是否启动异常,如果有就是会shutdown
        performPendingShutdown();
        //创建System的context
        createSystemContext();
        //创建SystemServiceManager,负责服务的启动
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        //LocalServices用于存储和管理Service
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    } finally {
        traceEnd();
    }
    try {
        //开启引导服务
        startBootstrapServices();
        //开启核心服务
        startCoreServices();
        //开启其他服务
        startOtherServices();
        //关闭之前启动的线程池
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        throw ex;
    } finally {
        traceEnd();
    }
    // 进入Loop循环,处理消息循环
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
初始化环境
最早时间设置

Android支持最早时间1970,如果当前时间还比这个早,那就把时间设置为1970

if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
    SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
时区设置

如果没有设置定过时区,就这只默认时区GMT

String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
    SystemProperties.set("persist.sys.timezone", "GMT");
}
语言环境设置

如果没有设置过语言,就设置默认的

if (!SystemProperties.get("persist.sys.language").isEmpty()) {
    final String languageTag = Locale.getDefault().toLanguageTag();
    SystemProperties.set("persist.sys.locale", languageTag);
    SystemProperties.set("persist.sys.language", "");
    SystemProperties.set("persist.sys.country", "");
    SystemProperties.set("persist.sys.localevar", "");
}
虚拟机设置
 //设置当前虚拟机的运行库路径
 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
 VMRuntime.getRuntime().clearGrowthLimit();
 //设置虚拟机堆内存
 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
Looper初始化

主线程Looper准备,这个都很熟悉了,这种Looper是不允许退出的,除非异常!

Looper.prepareMainLooper();
prepareMainLooper()
public static void prepareMainLooper() {
	//传入false,不允许退出
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

具体细节看《Android消息机制源码介绍》。

最后会进入Looper循环中。

// 进入Loop循环,处理消息循环
Looper.loop();
//如果退出了loop,就抛出异常。
throw new RuntimeException("Main thread loop unexpectedly exited");
加载so库

通过子线程加载了libandroid_servers.so

SystemServerInitThreadPool.get().submit(() -> {
System.loadLibrary("android_servers");
			}, "android_servers");

这里是通过线程加载so库的。

SystemServerInitThreadPool

SystemServerInitThreadPool这里是启动了线程池,后面还会用的。

//单例模式
public static synchronized SystemServerInitThreadPool get() {
    if (sInstance == null) {
        sInstance = new SystemServerInitThreadPool();
    }
    Preconditions.checkState(sInstance.mService != null, "Cannot get " + TAG
            + " - it has been shut down");
    return sInstance;
}
初始化Context

这里初始化了mSystemContext和systemUiContext

createSystemContext()
private void createSystemContext() {
	//创建activityThread对象
    ActivityThread activityThread = ActivityThread.systemMain();
	//获取系统上下文
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
	//获取SystemUI上下文
    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

细节暂不深入。

创建SystemServiceManager
//创建SystemServiceManager,负责服务的启动
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
        mRuntimeStartElapsedTime, mRuntimeStartUptime);
//LocalServices用于存储和管理Service
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
SystemServiceManager

这里重点介绍一下是启动服务的,后面的服务启动都是通过这个的。

这里以Installer启动为例。

Installer installer = mSystemServiceManager.startService(Installer.class);

这里的startService()查看是否能找到传入的className类么。

@SuppressWarnings("unchecked")
public SystemService startService(String className) {
    final Class<SystemService> serviceClass;
    try {
    	//返回className类对象
        serviceClass = (Class<SystemService>)Class.forName(className);
    } catch (ClassNotFoundException ex) {
    }
    //启动服务
    return startService(serviceClass);
}

接着的startService()主要作用:

  1. 判断serviceClass是否继承SystemService

  2. 获取构造函数初始化Service

  3. 调用真正启动服务的startService()

 @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            //isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系的。
			//serviceClass继承于SystemService
			//比如Installer extends SystemService
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
				//获取到构造函数
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
				//Service对象初始化
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            }
			//这里才真正启动启动Service
            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

真正启动服务的是在这个startService(),这里的工作是。

  1. 添加创建的service到mServices列表中,方便后续获取和查询

  2. 调用服务中的onStart()

public void startService(@NonNull final SystemService service) {
    //添加到服务列表,后面可以通过getService获取服务。
    mServices.add(service);
    try {
    	//调用服务中的onStart()
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
}
LocalServices

LocalServices很简单就是记录一下启动的服务。

public final class LocalServices {
    private LocalServices() {}
    private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
            new ArrayMap<Class<?>, Object>();

    @SuppressWarnings("unchecked")
    public static <T> T getService(Class<T> type) {
        synchronized (sLocalServiceObjects) {
            return (T) sLocalServiceObjects.get(type);
        }
    }
	//添加服务
    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);
        }
    }
	//异常服务
    @VisibleForTesting
    public static <T> void removeServiceForTest(Class<T> type) {
        synchronized (sLocalServiceObjects) {
            sLocalServiceObjects.remove(type);
        }
    }
}
启动服务

启动服务分三步

  1. 引导服务

  2. 核心服务

  3. 其他服务

 try {
	//引导服务
     startBootstrapServices();
	//核心服务
     startCoreServices();
	//其他服务
     startOtherServices();
     //关闭线程池
     SystemServerInitThreadPool.shutdown();
 } catch (Throwable ex) {
     throw ex;
 } finally {
     traceEnd();
 }
引导服务

引导服务都是比较重要的,也是后面服务需要用的。

这里主要启动了如下引导服务

  1. 安装服务(Installer)

  2. 设备认证服务(DeviceIdentifiersPolicyService)

  3. Activity管理服务(ActivityManagerService)

  4. 电源管理服务(PowerManagerService)

  5. 系统重启服务(RecoverySystemService)

  6. LED和屏幕背光管理服务(LightsService)

  7. 显示管理器服务(DisplayManagerService)

  8. 程序包管理服务(PackageManagerService)

  9. 多用户管理服务(UserManagerService)

  10. OverlayManagerService(不太懂,看字面意思层级管理服务)

  11. 传感器服务(这个主要native层)

private void startBootstrapServices() {
	//子线程初始化SystemConfig
    SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
	//启动Installer
    Installer installer = mSystemServiceManager.startService(Installer.class);
	//启动DeviceIdentifiersPolicyService
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    //子线程初始化mActivityManagerService
	mActivityManagerServiceStart = SystemServerInitThreadPool.get().submit(() -> {
        mActivityManagerService = mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
	 },"StartActivityManager");
    //启动PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    mActivityManagerService.initPowerManagement();
	//启动RecoverySystemService
    mSystemServiceManager.startService(RecoverySystemService.class);
	//启动LightsService
    mSystemServiceManager.startService(LightsService.class);
    // 启动SidekickService(这个根据条件启动)
    if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
        mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
    }
    //启动DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
	//启动PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    //启动UserManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
	//mActivityManagerService设置系统进程
    mActivityManagerService.setSystemProcess();
	//启动OverlayManagerService
    mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
	//启动传感器服务
    mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
		//native层启动传感器服务
        startSensorService();
    }, START_SENSOR_SERVICE);
}
核心服务

核心服务启动的个数就相对比较少了

  1. 电池管理服务(BatteryService)

  2. 跟踪应用使用情况(UsageStatsManagerInternal)

  3. WebView更新服务(WebViewUpdateService)

  4. Binder调用状态服务(BinderCallsStatsService)

private void startCoreServices() {
	//启动BatteryService
    mSystemServiceManager.startService(BatteryService.class);
	//启动UsageStatsService。收集用户使用每一个APP的频率、使用时常
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
    //启动WebViewUpdateService
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }
	//启动BinderCallsStatsService
    BinderCallsStatsService.start();
}
其他服务

这里启动的服务超级多,下面只简单介绍几个。

  1. 震动服务

ServiceManager.addService("vibrator", vibrator);
  1. 闹钟管理服务

mSystemServiceManager.startService(AlarmManagerService.class);
  1. 输入管理服务

inputManager = new InputManagerService(context);
  1. 窗口管理服务

wm = WindowManagerService.main(context, inputManager,
         mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
         !mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
         DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
         /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);

mActivityManagerService.setWindowManager(wm);

wm.onInitReady();
  1. HIDL服务

startHidlServices();
  1. 蓝牙服务

mSystemServiceManager.startService(BluetoothService.class);
  1. 存储管理器服务

storageManager = IStorageManager.Stub.asInterface(
                            ServiceManager.getService("mount"));
  1. WIFI相关服务

mSystemServiceManager.startService(WIFI_SERVICE_CLASS);

mSystemServiceManager.startService(
                        "com.android.server.wifi.rtt.RttService");

mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);

mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);

mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);

mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);

connectivity = new ConnectivityService(
    context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity,
            /* allowIsolated= */ false,
    DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
networkStats.bindConnectivityManager(connectivity);
networkPolicy.bindConnectivityManager(connectivity);
  1. 定位管理服务

ServiceManager.addService(Context.LOCATION_SERVICE, location);

参考文章

  1. Android进程系列第四篇---SystemServer进程的启动流程

  2. Android系统启动-SystemServer上篇

 历史上的今天

  1. 2020: 林清玄 :其实生活都一样,看你怎么想(0条评论)
  2. 2020: windows下FFmpeg使用以及ffmpeg抽取视频的关键帧(0条评论)
  3. 2019: android.view.ViewRootImpl$CalledFromWrongThreadException(0条评论)
  4. 2019: 朱湘:海外寄霓君(节选)(0条评论)
  5. 2018: Android6.0修改默认输入法(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

Android多窗口模式简单记录

前言在Android N以上设备,可以开启多窗口模式,也叫分屏模式,即在屏幕上可以同时显示多个窗口,这多个窗口可以是不同应用的,也可以是同一个应用的。正文禁用分屏app默认允许分屏,如果想要禁止分屏可以在AndroidManifest的Application节点或者Activity节点添加...

JNI之List集合

前言之前学了JNI中传输和创建对象数组,那如果穿集合呢?因此也整理一下,方便自己查阅。这里以ArrayList为例。正文还是在之前的基础改的,具体细节,这里不重复了。隐藏内容!评论可看后才能查看!评论可看参考文章《JNI开发-Java传递List集合对象到C/C++》《...

去除Notification提示音

前言Android开机时,notification通知会有提示音。这个是之前写的,重新摘抄于此。正文修改地方\androidp\frameworks\base\services\core\java\com\android\server\notification\Notificatio...

个人常用的GridView方法简介

前言Android中GridView还是比较常用的,GridView有些方法或者配置属性都是比较常用也比较容易忘记的。因此,今天抽空整(抄)理(袭)一下,以便查阅。PS: 现在RecyclerView比较多了正文GridView跟ListView有很多一样的属性或者方法。因此这里就更简...

《MySQL基础教程》笔记5

前言主要是记录一下select命令的使用。根据《MySQL基础教程-西泽梦路》学习,简单的做一下笔记。记录于此,方便自己回忆。正文我这以Window版的phpstudy软件验证。需要进入这个目录,才可以使用mysql命令D:\phpstudy_pro\Extensions\MySQL5...

徐志摩:认识你真好

一个人真正的魅力,不是你给对方留下了美好的第一印象;而是对方认识你多年后,仍喜欢和你在一起。也不是你瞬间吸引了对方的目光;而是对方熟悉你以后,依然欣赏你。更不是初次见面后,就有相见恨晚的感觉;而是历尽沧桑后,由衷倾诉说:认识你真好!认识你真好,虽然你不在我身边,却一直在心间。有一种目光不...