Android启动流程_SystemServer阶段

news2024/11/5 7:11:37

前言

上一篇文档我们描述了在 Android 启动流程中 Zygote 部分的内容,从 Zygote 的配置、启动、初始化等内容展开,描述了 Zygote 在 Android 启动中的功能逻辑。本篇文档将会继续 Android 启动流程的描述,从 SystemServer 进程的内容展开,继续了解 Android 是如何启动的。

正文

本篇文档将会从 SystemServer 进程的内容继续描述 Android 启动流程。对于 SystemServer 进程,主要是对服务的初始化顺序、重要服务列举、启动方式等方面展开,从整体的角度展开描述。

1、SystemServer 启动

SystemServer 启动从 main 函数开始运行,我们来看下此函数的逻辑:

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

SystemServer 的 main 函数中初始化了 SystemServer 对象,并且调用 run 函数执行,下面我们来看下 run 函数的逻辑:

private void run() {
    try {
        ......
        // 如果设备时间早于 1970 年,很多 API 处理负数时会 crash。所以直接设置为 1970 年 1 月 1 日
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        // 未设置时区的话默认设为 GMT
        String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
        if (timezoneProperty == null || timezoneProperty.isEmpty()) {
            Slog.w(TAG, "Timezone not set; setting to GMT.");
            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", "");
        }

        // The system server should never make non-oneway calls
        Binder.setWarnOnBlocking(true);
        // The system server should always load safe labels
        PackageItemInfo.setForceSafeLabels(true);

        // Default to FULL within the system server.
        SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;

        // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
        SQLiteCompatibilityWalFlags.init(null);

        // Here we go!
        Slog.i(TAG, "Entered the Android system server!");
        int uptimeMillis = (int) SystemClock.elapsedRealtime();
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
        if (!mRuntimeRestart) {
            MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
        }

        // 设置虚拟机运行库路径
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // Mmmmmm... more memory!
        // 清除虚拟机内存增长限制,允许应用申请更多内存
        VMRuntime.getRuntime().clearGrowthLimit();

        // 设置堆内存的有效利用率为 0.8,(可能被忽略)
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        // 确保指纹信息已经定义
        Build.ensureFingerprintProperty();

        // Within the system server, it is an error to access Environment paths without
        // explicitly specifying a user.
        Environment.setUserRequired(true);

        // Within the system server, any incoming Bundles should be defused
        // to avoid throwing BadParcelableException.
        BaseBundle.setShouldDefuse(true);

        // Within the system server, when parceling exceptions, include the stack trace
        Parcel.setStackTraceParceling(true);

        // 确保系统的 Binder 调用总是运行在前台优先级
        BinderInternal.disableBackgroundScheduling(true);

        // Increase the number of binder threads in system_server
        BinderInternal.setMaxThreads(sMaxBinderThreads);

        // Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
        // 1. 创建主线程 Looper
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        // 初始化 native 服务,加载 libandroid_servers.so
        System.loadLibrary("android_servers");

        // 检查上次关机是否失败,可能不会有返回值
        performPendingShutdown();

        // 2. 初始化系统上下文
        createSystemContext();

        // 3. 创建系统服务管理 SystemServiceManager
        // 并将 mSystemServiceManager 注册到 sLocalServiceObjects 中
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices(); // 4. 启动系统引导服务
        startCoreServices();      // 5. 启动系统核心服务
        startOtherServices();     // 6. 启动其他服务
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    StrictMode.initVmDefaults(null);

    if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
        int uptimeMillis = (int) SystemClock.elapsedRealtime();
        MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
        final int MAX_UPTIME_MILLIS = 60 * 1000;
        if (uptimeMillis > MAX_UPTIME_MILLIS) {
            Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                    "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
        }
    }

    // 7. Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

上述代码是 run 函数的主要内容,简单概括功能如下:

A:设置默认时间、时区、语言等参数

B:创建主线程的 Looper

C:初始化系统上下文

D:创建系统服务管理类 SystemServiceManager

E:按顺序启动系统服务,启动顺序为 BootStarpService、CoreService、OtherService

F:启动 Loop 循环处理消息

下面我们将会根据流程来描述 SystemServer 的运行过程。

2、SystemServer 启动阶段

2.1 设置默认时间、时区、语言

在 SystemServer 的 run() 函数中,会先对系统时间进行默认设置,如果设备时间早于 1970 年,那么时间戳就是负数(1970-01-01 00:00:00+0000 时间戳为 0),很多 API 在处理负数时会 crash。所以这里要先将时间设置成默认值 1970 年 1 月 1 日。

Android 通过属性来配置语言数据,persist.sys.language 属性定义了系统的默认语言。

2.1.1 Android 中时间标准和时区
  • 原子时:International Atomic Time (IAT)

又称国际原子时,是一种通过原子钟得到的时间标准,原子钟是世界上已知最准确的时间测量和频率标准,原子钟在 37 亿年的误差不超过 1 秒。

  • 世界时:Universal Time(UT)

在格林尼治子午线上的平太阳时称为世界时(UT0),又叫格林尼治平时(GMT)。格林尼治标准时间(旧译格林尼治平均时间或格林威治标准时间,英语:Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。

  • 协调世界时:Coordinated Universal Time(UTC)

又称世界标准时间、世界统一时间。是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以“秒”为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以“世界标准时间”的角度来说,UTC比GMT更精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。UTC被应用在大多数的计算机以及网络标准中。

2.1.2 GMT 时间和 UTC 时间的区别

GMT(格林威治标准时间)和 UTC(协调世界时)是两种常用的时间标准,它们之间有一些相似之处,但也存在一些重要的区别:

相似之处

  • 时间基准: GMT 和 UTC 都是用于表示时间的基准,通常用于协调不同地区的时间。

  • 时间格式: 两者都可以表示为小时和分钟的格式,例如 GMT+8:00 或 UTC+8:00。

主要区别

  • 定义:

GMT: 是一种基于地球自转的时间标准,最初是以格林威治天文台为基准。它反映的是地球自转与太阳位置之间的关系。

UTC: 是一种更精确的时间标准,基于原子钟的时间测量。UTC 是国际上广泛使用的时间标准,不受地球自转变化的影响。

  • 精度:

GMT: 随着地球自转的不规则性,GMT 的精度相对较低。

UTC: 通过引入闰秒来调整,使其与地球自转保持一致,因而更为精确。

  • 使用场景:

GMT: 在某些地区和特定场合(如航海和航空)仍然被使用。

UTC: 是现代计算机系统、网络协议(如 NTP)和全球时间标准的基础。

虽然 GMT 和 UTC 在日常使用中常常可以互换,但在技术和科学领域,UTC 更为准确和可靠。对于编程和系统设计,推荐使用 UTC 作为时间标准。

2.1.3 时间戳

时间戳是指某个特定时间点的标识,通常是一个数字或字符串。它表示从某个固定的起始时间(通常是1970 年1月1日00:00:00 UTC)到该时间点所经过的秒数或毫秒数。时间戳可以用于记录事件发生的时间、计算时间间隔、进行时间排序等操作。

注意:时间戳的优点是具有唯一性和可比较性,不受时区和地域的影响(也就是说,在全世界任何时区,获取的时间戳都是一样的)。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"Locale.getDefault());
Log.i("Test", sdf.parse("2018-09-01 08:00:00+0800").getTime()+"");
Log.i("Test", sdf.parse("2018-09-01 00:00:00+0000").getTime()+"");
Log.i("Test", sdf.parse("1970-01-01 00:00:00+0000").getTime()+"");

运行结果:
    1535760000000
    1535760000000
    0

相同时间对应不同的时区的时间,在转换成时间戳得到的值是一致的。

2.1.4 修改默认语言

  • 修改 PRODUCT_LOCALES 字段

在 /build/target/product/languages_full.mk 文件中 PRODUCT_LOCALES 字段定义了所有的语言,系统的默认语言是因为,第一位是 en_US,如果修改,可以将要修改的语言放在第一位,例如 zh_CN。

  • 修改device/{硬件平台}/{产品}/system.prop或者default.prop,加入:
[persist.sys.language]: [zh]
[persist.sys.country]: [CN]
  • 修改 init.rc
setprop persist.sys.language zh
setprop persist.sys.country CN
  • 修改device/{硬件平台}/{产品}/device.mk,加入:
PRODUCT_PROPERTY_OVERRIDES += \
	persist.sys.language=zh \
	persist.sys.country=CN \
  • 修改build/tools/buildinfo.sh
echo "persist.sys.language=zh"
echo "persist.sys.country=CN"

3、Service 服务的启动

本章节将会介绍服务的启动流程,在 SystemServer 中会启动 Android 上层服务,用于支持 Android 的各类功能,下列小章节将会从服务启动的介绍、启动阶段和启动方式展开描述。

3.1 服务启动介绍

SystemServer 通过如下三个函数进行各类服务的启动

startBootstrapServices(); // 4. 启动系统引导服务
startCoreServices();      // 5. 启动系统核心服务
startOtherServices();     // 6. 启动其他服务
3.1.1 startBootstrapServices

startBootstrapServices 函数用于启动系统引导服务,启动的内容如下所示:

private void startBootstrapServices() {
    final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
    SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);

    // 阻塞等待与 installd 建立 socket 通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    // 启动 DeviceIdentifiersPolicyService,在 ActivityManagerService 之前
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);

    // 启动服务 ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    // 启动服务 PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    // Now that the power manager has been started, let the activity manager
    // initialize power management features.
    mActivityManagerService.initPowerManagement();

    // 启动服务 RecoverySystemService
    mSystemServiceManager.startService(RecoverySystemService.class);

    // Now that we have the bare essentials of the OS up and running, take
    // note that we just booted, which might send out a rescue party if
    // we're stuck in a runtime restart loop.
    RescueParty.noteBoot(mSystemContext);

    // 启动服务 LightsService
    mSystemServiceManager.startService(LightsService.class);

    // Package manager isn't started yet; need to use SysProp not hardware feature
    if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
        mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
    }

    // 启动 DisplayManagerService,在 PackageManagerService 之前
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    // We need the default display before we can initialize the package manager.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    // 正在加密设备时只运行核心 app
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        Slog.w(TAG, "Device encrypted - only parsing core apps");
        mOnlyCore = true;
    }

    // 启动服务 PackageManagerService
    if (!mRuntimeRestart) {
        MetricsLogger.histogram(null, "boot_package_manager_init_start",
                (int) SystemClock.elapsedRealtime());
    }
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
        MetricsLogger.histogram(null, "boot_package_manager_init_ready",
                (int) SystemClock.elapsedRealtime());
    }
    if (!mOnlyCore) {
        boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                false);
        if (!disableOtaDexopt) {
            traceBeginAndSlog("StartOtaDexOptService");
            try {
                OtaDexoptService.main(mSystemContext, mPackageManagerService);
            } catch (Throwable e) {
                reportWtf("starting OtaDexOptService", e);
            } finally {
                traceEnd();
            }
        }
    }

    // 启动服务 UserManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);

    // 初始化属性 cache 以缓存包资源
    AttributeCache.init(mSystemContext);

    // 设置 AMS
    mActivityManagerService.setSystemProcess();

    // DisplayManagerService needs to setup android.display scheduling related policies
    // since setSystemProcess() would have overridden policies due to setProcessGroup
    mDisplayManagerService.setupSchedulerPolicies();

    // 启动服务 OverlayManagerService
    OverlayManagerService overlayManagerService = new OverlayManagerService(
            mSystemContext, installer);
    mSystemServiceManager.startService(overlayManagerService);

    if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
        // DisplayManager needs the overlay immediately.
        overlayManagerService.updateSystemUiContext();
        LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
    }

    // 在单独的线程中启动 SensorService
    mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
        TimingsTraceLog traceLog = new TimingsTraceLog(
                SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
        startSensorService();
    }, START_SENSOR_SERVICE);
}

启动的服务列表入下表所示:

服务名称描述
Installer负责apk安装相关的工作
DeviceIdentifiersPolicyService设备标识符策略服务
UriGrantsManagerServiceUri授权管理
ActivityTaskManagerService用于管理Activity及其容器(task, stacks, displays,… )的系统服务
ActivityManagerService管理Activity的启动,调度等工作
PowerManagerService负责协调设备上的电源管理功能
ThermalManagerService热缓解服务
RecoverySystemService负责协调设备上与恢复有关的功能
LightsService管理LED和屏幕背光
DisplayManagerService管理显示设备
PackageManagerService主要负责APK、jar包的管理
UserManagerService管理用户的系统服务
OverlayManagerService负责动态资源overlay工作,具体请搜索android RRO技术
SensorPrivacyService和传感器有关,具体作用不明
SensorPrivacySere传感器服务
3.1.2 startCoreServices

startCoreServices 函数用于启动 SystemServer 中的核心服务。

private void startCoreServices() {
        // 追踪电池充电状态和电量。需要LightService
        mSystemServiceManager.startService(BatteryService.class);

         //跟踪应用程序使用状态
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));

        // 跟踪可更新的WebView是否处于就绪状态,并监视更新安装。
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
            traceBeginAndSlog("StartWebViewUpdateService");
            mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
            traceEnd();
        }

       //跟踪并缓存设备状态。
        mSystemServiceManager.startService(CachedDeviceStateService.class);

        // 跟踪在Binder调用中花费的cpu时间
        mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);

        // 跟踪handlers中处理messages所花费的时间。
        mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);

        //管理apk回滚
        mSystemServiceManager.startService(RollbackManagerService.class);

        // 用于捕获bugreport,adb bugreport 命令调用的就是这个服务
        mSystemServiceManager.startService(BugreportManagerService.class);

        // 管理Gpu和Gpu驱动的服务
        mSystemServiceManager.startService(GpuService.class);
    }

核心服务如下表所示:

服务名称描述
BatteryService追踪电池充电状态和电量
UsageStatsManagerInternal跟踪应用程序使用状态
WebViewUpdateService跟踪可更新的WebView是否处于就绪状态,并监视更新安装。
CachedDeviceStateService跟踪并缓存设备状态
BinderCallsStatsService跟踪在Binder调用中花费的cpu时间
LooperStatsService跟踪handlers中处理messages所花费的时间。
RollbackManagerService管理apk回滚
BugreportManagerService用于捕获bugreport
GpuService管理Gpu和Gpu驱动
3.1.3 startOtherServices

startOtherServices 用于启动 SystemServer 中的其他服务,在这个方法中启动的服务比较多。

KeyAttestationApplicationIdProviderService/KeyChainSystemService
SchedulingPolicyService/TelecomLoaderService/TelephonyRegistry

mContentResolver = context.getContentResolver();

AccountManagerService/ContentService

mActivityManagerService.installSystemProviders();
  
DropBoxManagerService/VibratorService/ConsumerIrService/AlarmManagerService

final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);

InputManagerService/WindowManagerService/VrManagerService/BluetoothService
IpConnectivityMetrics/NetworkWatchlistService/PinnerService
InputMethodManagerService/AccessibilityManagerService/StorageManagerService
StorageStatsService/UiModeManagerService/LockSettingsService
PersistentDataBlockService/OemLockService/DeviceIdleController
DevicePolicyManagerService/StatusBarManagerService/ClipboardService
NetworkManagementService/IpSecService/TextServicesManagerService
TextClassificationManagerService/NetworkScoreService/NetworkStatsService
NetworkPolicyManagerService/WifiScanningService/RttService
WifiAware/WifiP2P/Lowpan/Ethernet/ConnectivityService/NsdService
SystemUpdateManagerService/UpdateLockService/NotificationManagerService
DeviceStorageMonitorService/LocationManagerService/CountryDetectorService
SearchManagerService/WallpaperManagerService/AudioService/BroadcastRadioService
DockObserver/ThermalObserver/WiredAccessoryManager/MidiManager/UsbService
SerialService/HardwarePropertiesManagerService/TwilightService
ColorDisplayService/JobSchedulerService/SoundTriggerService/TrustManagerService
BackupManager/AppWidgerService/VoiceRecognitionManager/GestureLauncherService
SensorNotificationService/ContextHubSystemService/DiskStatsService
TimeZoneRulesManagerService/NetworkTimeUpdateService/CommonTimeManagementService
CertBlacklister/EmergencyAffordanceService/DreamManagerService/GraphicsStatsService
CoverageService/PrintManager/CompanionDeviceManager/RestrictionsManagerService
MediaSessionService/MediaUpdateService/HdmiControlService/TvInputManagerService
MediaResourceMonitorService/TvRemoteService/MediaRouterService/FingerprintService
BackgroundDexOptService/PruneInstantAppsJobService/ShortcutService
LauncherAppsService/CrossProfileAppsService/MediaProjectionManagerService
WearConfigService/WearConnectivityService/WearTimeService/WearLeftyService
WearGlobalActionsService/SliceManagerService/CameraServiceProxy/IoTSystemService
MmsServiceBroker/AutoFillService

// It is now time to start up the app processes...
vibrator.systemReady();
lockSettings.systemReady();

// 480
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); 
// 500
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); 

wm.systemReady();
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(safeMode, mOnlyCore);

// Start device specific services
final String[] classes = mSystemContext.getResources().getStringArray(
        R.array.config_deviceSpecificSystemServices);
for (final String className : classes) {
    try {
        mSystemServiceManager.startService(className);
    } catch (Throwable e) {
        reportWtf("starting " + className, e);
    }
}

// 520
mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

mActivityManagerService.systemReady(() -> {
    // 550
    mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
    
    startSystemUi(context, windowManagerF);
    
    networkManagementF.systemReady();
    ipSecServiceF.systemReady();
    networkStatsF.systemReady();
    connectivityF.systemReady();
    
    Watchdog.getInstance().start
    mPackageManagerService.waitForAppDataPrepared();

    // 600
    mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    
    locationF.systemRunning();
    countryDetectorF.systemRunning();
    networkTimeUpdaterF.systemRunning();
    commonTimeMgmtServiceF.systemRunning();
    inputManagerF.systemRunning();
    telephonyRegistryF.systemRunning();
    mediaRouterF.systemRunning();
    mmsServiceF.systemRunning();
    incident.systemRunning();
}

这部分启动的服务比较多,具体的服务如下图所示:

image.png

3.2 服务启动阶段

在服务的启动过程中,我们可以看到会调用 mSystemServiceManager.startBootPhase() 函数进行启动阶段的逻辑执行。

启动阶段定义在 android/frameworks/base/services/core/java/com/android/server/SystemService.java 文件中。

/*
 * Boot Phases
 * 
 * 启动阶段
 */
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?

/**
 * After receiving this boot phase, services can obtain lock settings data.
 */
public static final int PHASE_LOCK_SETTINGS_READY = 480;

/**
 * After receiving this boot phase, services can safely call into core system services
 * such as the PowerManager or PackageManager.
 * 
 * 在这个阶段之后,可以安全的调用系统核心服务,如 PowerManager 和 PackageManager
 */
public static final int PHASE_SYSTEM_SERVICES_READY = 500;

/**
 * After receiving this boot phase, services can safely call into device specific services.
 * 
 * 在这个阶段之后,可以安全调用设备特定的服务
 */
public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

/**
 * After receiving this boot phase, services can broadcast Intents.
 * 
 * 在这个阶段之后,服务可以广播
 */
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

/**
 * After receiving this boot phase, services can start/bind to third party apps.
 * Apps will be able to make Binder calls into services at this point.
 * 
 * 在这个阶段之后,服务可以启动/绑定第三方应用
 * 应用此时可以进行 Binder 调用
 */
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

/**
 * After receiving this boot phase, services can allow user interaction with the device.
 * This phase occurs when boot has completed and the home application has started.
 * System services may prefer to listen to this phase rather than registering a
 * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
 * 
 * 在这个阶段之后,允许用户和设备交互。
 * 这个阶段发生在启动完成,home 应用已经开始。
 * 系统服务更倾向于监听这个阶段,而不是监听启动广播 ACTION_BOOT_COMPLETED,以降低延迟
 */
public static final int PHASE_BOOT_COMPLETED = 1000;

这些启动阶段会穿插在各项的服务启动序列中,每一个启动阶段节点的插入,都会伴随着该启动阶段节点之前的服务执行相关逻辑。

所以这里启动阶段节点相对于标识或者说依赖关系,即后续的启动阶段需要依赖于前面某些服务的特色处理逻辑之后才能进行。

在系统启动过程中,启动阶段的大致流程如下所示:

private void startBootstrapServices() {
    ...
    // 100
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    ...
}

private void startOtherServices() {
    ...
    // 480
    mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
    // 500
    mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);

    ...
    // 520
    mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

    mActivityManagerService.systemReady(() -> {
        mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY); // 550
                    
        ...
        mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); // 600
    }
}
  // 最后的 SystemService.PHASE_BOOT_COMPLETED(1000) 在 AMS 的 finishBooting() 方法中调用。

系统通过 startBootPhase 函数去开启启动时的关键节点。

startBootPhase -> onBootPhase的设计,是对Service之间、以及Service对系统各阶段依赖性的一个处理。在启动过程中各阶段的优化工作上是一个切入点。

下面引用图为梳理服务角色的关系:

请添加图片描述

3.3 服务启动方式

SystemServiceManager.startService 函数在 SystemServer 中用于启动系统服务,我们来看下系统服务的启动方式。

public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        // 获取服务名称
        final String name = serviceClass.getName();

        // Create the service.
        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);
        } 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);
        }

        startService(service);
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

创建并启动一个系统服务。这个系统服务必须是 com.android.server.SystemService 的子类。根据参数传入的 Class 对象反射创建其实例,再调用重载方法 startService()

public void startService(@NonNull final SystemService service) {
    // Register it.
    mServices.add(service);
    // Start it.
    long time = SystemClock.elapsedRealtime();
    try {
        // 回调系统服务的 onStart() 方法
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
            + ": onStart threw an exception", ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}

就两步。第一步,注册服务,mServices 是一个 ArrayList<SystemService> 对象,用来保存已经创建的系统服务。第二步,回调服务的 onStart() 方法,还是以 Installer 为例:

@Override
public void onStart() {
    if (mIsolated) {
        mInstalld = null;
    } else {
        connect();
    }
}

这样一个服务就启动完成了。这是一种比较普遍的启动方式。

总结

final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
// 回调系统服务的 onStart() 方法
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ “: onStart threw an exception”, ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, “onStart”);
}


就两步。第一步,注册服务,`mServices` 是一个 `ArrayList<SystemService>` 对象,用来保存已经创建的系统服务。第二步,回调服务的 `onStart()` 方法,还是以 `Installer` 为例:

```java
@Override
public void onStart() {
    if (mIsolated) {
        mInstalld = null;
    } else {
        connect();
    }
}

这样一个服务就启动完成了。这是一种比较普遍的启动方式。

总结

本篇文章主要描述了 Android 启动过程中 SystemServer 阶段的逻辑,从SystemServer 中服务展开描述,大致整理了 SystemServer 启动服务的流程、启动阶段、启动服务的方式等。从整体流程大致记录,具体细节仍需学习。本篇文章由于时间关系,引用内容较多,内容较为基本。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

启动任务节点时,传入机械臂参数

MoveIt2_tutorial-Examples-Planning Scene ROS API 先启动move_group节点&#xff0c;后启动任务节点 方式1&#xff1a; 直接传入参数文件的地址 from launch import LaunchDescription # 导入启动描述&#xff0c;用于描述启动文件的结构 from launch_ros.actions impor…

HarmonyOS NEXT星河版笔记--ArkTS篇(1)

一、概念 ArkTS&#xff1a;是一门用于开发鸿蒙应用的编程语言 console.log(我说,HelloWorld) 二、认识数据 2.1.基础数据类型 string字符串描述信息number数字计算boolean布尔判断&#xff08;真、假&#xff09; 2.2.存储数据 存储数据包括变量和常量。 2.2.1.变量&a…

【数据结构】ArrayList的模拟实现--Java

目录 一、&#x1f369;简单了解ArrayList 二、&#x1f369;ArrayList的简单模拟实现 1.&#x1f354;IList接口 1.&#x1f355;IList接口 2. &#x1f355; MyArrayList 重写接口方法 2.&#x1f354;ArrayList方法 1.&#x1f96a;增 1.add&#xff08;添加元素&…

数据结构+算法

一、数据结构 1、线性结构 数组&#xff1a; 访问&#xff1a;O(1)访问特定位置的元素&#xff1b;插入&#xff1a;O(n)最坏的情况发生在插入发生在数组的首部并需要移动所有元素时&#xff1b;删除&#xff1a;O(n)最坏的情况发生在删除数组的开头发生并需要移动第一元素后…

go 聊天系统项目-1

1、登录界面 说明&#xff1a;这一节的内容采用 go mod 管理【GO111MODULE‘’】的模块&#xff0c;从第二节开始使用【GO111MODULE‘off’】GOPATH 管理模块。具体参见 go 包相关知识 1.1登录界面代码目录结构 代码所在目录/Users/zld/Go-project/day8/chatroom/ 1.2登录…

Steam deck 倒腾日记 - 安装Windows软件,玩上黑神话悟空

Steam deck 倒腾日记 关于Steam Deck基本信息性能特点游戏兼容性 问题一: 软键盘输入问题二: 系统切换问题三: 安装运行Window 软件关于Proton如何运行 问题四: 优化网络问题黑神话.悟空PS参考 关于Steam Deck Steam Deck是一款由Valve开发的便携式游戏PC&#xff0c;它搭载了A…

【内网渗透】最保姆级的2022网鼎杯半决赛复盘打靶笔记

目录 flag1 flag2 flag3 flag4 flag1 fscan什么也没扫到 访问是个web dirsearch开扫 访问./wp-admin 弱口令admin:123456登录 编辑主题文件 在header.php中插入一句话木马 header.php位置&#xff1a;https://tw.godaddy.com/help/change-the-header-in-wordpress-264…

Python 实现斐波那契数列的方法

以下是使用 Python 实现斐波那契数列的方法&#xff1a; def fibonacci(n): if n < 1: return n else: return fibonacci(n - 1) fibonacci(n - 2) # 打印前 10 个斐波那契数 for i in range(10): print(fibonacci(i)) 在这个代码中&#xff0c;定义了一个函数 fibonacc…

IntelliJ IDEA 中上传项目到 Gitee 的完整指南

博主主页:【南鸢1.0】 本文专栏&#xff1a;git 目录 简介 1.插入intellij-gitee 2.导入下载插件 3.选择导航栏中的VCS->Share Project on Gitee 4.登录gitee 6.验证gitee仓库是否创建成功 7.上传分享项目 8.验证仓库代码是否上传成功 总结 简介 Gitee 是一个代码…

【p2p、分布式,区块链笔记 分布式容错算法】: 拜占庭将军问题+实用拜占庭容错算法PBFT

papercodehttps://pmg.csail.mit.edu/papers/osdi99.pdfhttps://github.com/luckydonald/pbft 其他相关实现&#xff1a;This is an implementation of the Pracltical Byzantine Fault Tolerance protocol using PythonAn implementation of the PBFT consensus algorithm us…

简单的kafkaredis学习之redis

简单的kafka&redis学习之redis 2. Redis 2.1 什么是Redis Redis是一种面向 “Key-Value” 数据类型的内存数据库&#xff0c;可以满足我们对海量数据的快速读写需求&#xff0c;Redis是一个 NoSQL 数据库&#xff0c;NoSQL的全称是not only sql&#xff0c;不仅仅是SQL&…

无人机之卫星通信技术篇

无人机的卫星通信技术是一种利用人造地球卫星作为中继站来转发无线电波&#xff0c;从而实现无人机与地面控制站之间通信的技术。 一、技术概述 卫星通信系统主要由通信卫星和经该卫星连通的地球站两部分组成。在无人机应用中&#xff0c;卫星通信技术能够确保无人机在全球范围…

网鼎杯 misc -好久不见4

不嘻嘻&#xff0c;没见过这种题&#xff0c;需要把这个红线还原重组成二维码&#xff0c;搜索一个是这个Peano曲线 from PIL import Image from tqdm import tqdmdef peano(n):if n 0:return [[0, 0]]else:in_lst peano(n - 1)lst in_lst.copy()px, py lst[-1]lst.extend(…

ARM base instruction -- adcs

Add with Carry, setting flags, adds two register values and the Carry flag value, and writes the result to the destination register. It updates the condition flags based on the result. 带进位加法&#xff0c;设置标志&#xff0c;将两个寄存器值和进位标志值相…

笔记本双系统win10+Ubuntu 20.04 无法调节亮度亲测解决

sudo add-apt-repository ppa:apandada1/brightness-controller sudo apt-get update sudo apt-get install brightness-controller-simple 安装好后找到一个太阳的图标&#xff0c;就是这个软件&#xff0c;打开后调整brightness&#xff0c;就可以调整亮度&#xff0c;可…

vue版本太低无法执行vue ui命令

连接 ui和create目前都只支持3.0以后得版本才能使用 https://blog.csdn.net/m0_67318913/article/details/136775252?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-136775252-blog-121204604.235v43pc_blog_bottom_relevance…

萤石私有化设备视频平台EasyCVR视频融合平台如何构建农业综合监控监管系统?

现代农业的迅速发展中&#xff0c;集成监控管理系统已成为提高农业生产效率和优化管理的关键工具。萤石私有化设备视频平台EasyCVR&#xff0c;作为一个具有高度可扩展性、灵活的视频处理能力和便捷的部署方式的视频监控解决方案&#xff0c;为农业监控系统的建设提供了坚实的技…

Pr 视频效果:闪光灯

视频效果/风格化/闪光灯 Stylize/Strobe Light 闪光灯 Strobe Light效果可用于在视频中创建闪烁或频闪的效果&#xff0c;类似于舞台上的频闪灯或摄影中的闪光灯。 ◆ ◆ ◆ 效果选项说明 通过调整各种参数&#xff0c;可以自定义闪光的颜色、频率、持续时间和混合模式&#…

FreeRTOS确定任务栈大小

一、FreeRTOS内存分配 所有任务共用一个堆空间&#xff0c;所以当调用xPortGetFreeHeapSize这个函数时&#xff0c;返回的就是现在所有可用堆空间的消息 所有任务都有自己的栈空间&#xff0c;比如在任务中定义一个uint32_t data[100]的数组&#xff0c;此时调用uxTaskGetSt…

计算机毕业设计Hadoop+Spark+Hive抖音情感分析 抖音可视化 抖音舆情监测 预测算法 抖音爬虫 抖音大数据 情感分析 NLP 自然语言处理

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; HadoopSparkHive抖音情感分…