This article is based on Android 9.0, code repository address: Android_9.0.0_r45
Article source link:
SystemServer.java
SystemServiceManager.java
SystemService.java
First of all, let’s review the previous article on the Java world of Pangu and Nuwa — Zygote, mainly introduced the Android world’s first Java process Zygote, its main workflow is as follows:
registerServerSocketFromEnv()
Registers the server socket for communicating with the client processpreload()
, preloads a series of resources to improve application startup speedforkSystemServer()
To createsystem_server
process- Retire with success, call
runSelectLoop()
Wait for a response to a client request to create an application process
The main process in this article, system_server, is the first process fork from Zygote and is responsible for managing and starting the entire Framework layer.
Take a look at Gityuan’s image again and find the location of the System Server, which hosts the creation and startup of various System services. The system_server process creation process is described in detail in the previous article. Here is a brief flow chart:
The systemServer.main () method is eventually called. Here is a starting point for a detailed analysis of what SystemServer does.
SystemServer Startup process
public static void main(String[] args) {
new SystemServer().run();
}
Copy the code
Now look at the run() method.
private void run(a) {
try{...// If the device is older than 1970, many apis will crash when handling negative numbers. So I just set it to January 1, 1970
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
// If the time zone is not set, the GMT is set by default
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");
}
// Language locale Settings
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);
}
// Set the vm runtime path
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Mmmmmm... more memory!
// Clear the vm memory growth limit to allow applications to apply for more memory
VMRuntime.getRuntime().clearGrowthLimit();
// Set the effective utilization of heap memory to 0.8, (which may be ignored)
VMRuntime.getRuntime().setTargetHeapUtilization(0.8 f);
// Make sure fingerprint information is defined
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);
// Make sure the system's Binder calls always run at foreground priority
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. Create the main thread Looper
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
// Initialize the native service and load libandroid_servers.so
System.loadLibrary("android_servers");
// Check whether the last shutdown failed, there may be no return value
performPendingShutdown();
// 2. Initialize system context
createSystemContext();
// 3. Create SystemServiceManager
// Register mSystemServiceManager with 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. Start the boot service
startCoreServices(); // 5. Start core services
startOtherServices(); // 6. Start other services
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");
}
Copy the code
The code is longer, but the logic is clear. I’ve highlighted the seven most important steps in the comments, and I’m going through them one by one.
Looper.prepareMainLooper()
Initialize Looper. For an in-depth understanding of the Handler messaging mechanism, read my other article. Looper.loop() is finally called to open the message loop and begin processing the message.
createSystemContext()
private void createSystemContext(a) {
// Create system_server context information
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
// Set the theme for the system dialog, etc
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
Copy the code
Create the system context. First call ActivityThread. SystemMain () method to obtain ActivityThread object, and then obtain the context.
public static ActivityThread systemMain(a) {
// Do not enable hardware acceleration on low-memory devices
if(! ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true.0);
return thread;
}
Copy the code
The ActivityThread.attach() method won’t be analyzed here, but will be explained later when the application starts.
Once the system context is created, it’s time to start the various system services. The source code broadly divides services into three categories, to review:
startBootstrapServices(); // 4. Start the boot service
startCoreServices(); // 5. Start core services
startOtherServices(); // 6. Start other services
Copy the code
Analyze one by one.
startBootstrapServices()
private void startBootstrapServices(a) {
final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
// Block waiting to establish socket channel with instalLD
Installer installer = mSystemServiceManager.startService(Installer.class);
/ / start DeviceIdentifiersPolicyService, before ActivityManagerService
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
// Start ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
// Start the service PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Now that the power manager has been started, let the activity manager
// initialize power management features.
mActivityManagerService.initPowerManagement();
// Start the service 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);
// Start 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);
}
// Start DisplayManagerService before 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);
// Run only the core app while encrypting the device
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;
}
// Start 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(); }}}// Start UserManagerService
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
// Initialize attribute cache to cache package resources
AttributeCache.init(mSystemContext);
/ / set the AMS
mActivityManagerService.setSystemProcess();
// DisplayManagerService needs to setup android.display scheduling related policies
// since setSystemProcess() would have overridden policies due to setProcessGroup
mDisplayManagerService.setupSchedulerPolicies();
// Start 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();
}
// Start SensorService in a separate thread
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
startSensorService();
}, START_SENSOR_SERVICE);
}
Copy the code
StartBootstrapServices () method are all key services in the process of system startup and depend on each other. The main services are as follows:
Installer
DeviceIdentifiersPolicyService
ActivityManagerService
PowerManagerService
RecoverySystemService
LightsService
StartSidekickService
DisplayManagerService
SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY (100)
PackageManagerService
UserManagerService
OverlayManagerService
SensorService
Twelve core services were launched. PHASE_WAIT_FOR_DEFAULT_DISPLAY, which does not represent a SystemService. Instead, it is an int value of 100. There are other similar ints defined in the SystemService class. Its purpose is to divide the service startup process into phases, each of which has a specific meaning and can do different things. Here is a brief introduction of all the services, and then come back to summarize the stages.
startCoreServices()
private void startCoreServices(a) {
LightService is required to start BatteryService
mSystemServiceManager.startService(BatteryService.class);
// Start UsageStatsService to collect statistics on application usage
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Check if there is an updatable WebView. Start the service WebViewUpdateService if it exists
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}
// Start BinderCallsStatsService to track CPU consumption for Binder calls
BinderCallsStatsService.start();
}
Copy the code
Four services are started, BatteryService UsageStatsService WebViewUpdateService and BinderCallsStatsService.
startOtherServices()
StartOtherServices () has more than a thousand lines of source code, like a grocery store, launching a series of services. Let’s simplify the code as much as possible:
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();
}
Copy the code
You can see from the above code that quite a few system services are started. The startOtherServices() method goes through five startup phases, as shown below:
SystemService.PHASE_LOCK_SETTINGS_READY / / 480
SystemService.PHASE_SYSTEM_SERVICES_READY / / 500
SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY / / 520
SystemService.PHASE_ACTIVITY_MANAGER_READY / / 550
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START / / 600
Copy the code
The last call mActivityManagerService. SystemReady () method. In this method, startHomeActivityLocked is called to start the desktop Activity, and the desktop application is started.
Looper.loop()
The system_server process enters the looper.loop () state and waits for other threads to send messages to the main thread via Handler and process them.
SystemServer startup classification
Come back to look at the aforementioned start stage classification, defined in the com. Android. Server SystemService class:
/* * 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. * * after this stage, Can safely call system core services, such as PowerManager and PackageManager */
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
/** * After receiving this boot phase, services can safely call into device specific services. Device-specific services can be safely called */
public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;
/** * After receiving this boot phase, services can broadcast Intents. ** After this 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. * * After this stage, the service can launch/bind third-party applications * the application can then make Binder calls */
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. * * After this phase, the user is allowed to interact with the device. * This phase occurs when the startup is complete and the home application has started. * System services prefer to listen on this phase rather than on the start broadcast ACTION_BOOT_COMPLETED to reduce latency */
public static final int PHASE_BOOT_COMPLETED = 1000;
Copy the code
The positions of the various stages in the system_server startup process are roughly as follows:
private void startBootstrapServices(a) {.../ / 100mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); . }private void startOtherServices(a) {.../ / 480
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
/ / 500mSystemServiceManager.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}}Copy the code
The final systemservice.phase_boot_completed (1000) is called in AMS’s finishBooting() method. Notice also that the 480 and 500 phases are connected, and nothing happens in between.
So, what exactly is the function of compartmentalization? The answer is in the startBootPhase() method:
public void startBootPhase(final int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
try {
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
long time = SystemClock.elapsedRealtime();
try {
// Call back the onBootPhase() method of the system service
service.onBootPhase(mCurrentPhase);
} catch (Exception ex) {
throw new RuntimeException("Failed to boot service "
+ service.getClass().getName()
+ ": onBootPhase threw an exception during phase "
+ mCurrentPhase, ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase"); }}finally{ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); }}Copy the code
The core is service.onBootPhase(mCurrentPhase); . All system services inherit from SystemService, and the startBootPhase() method calls back the onBootPhase() method of all system services that have been added to mServices in the current phase to do something appropriate at the appropriate phase. Take AMS as an example:
@Override
public void onBootPhase(int phase) {
mService.mBootPhase = phase;
if(phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); }}Copy the code
How does SystemServer start services?
Read SystemServer source code, its most important work is to create and start a variety of system services. So how are services typically created? The Installer, the first service created in startBootstrapServices(), is used as an example:
Installer installer = mSystemServiceManager.startService(Installer.class);
Copy the code
Enter the SystemServiceManager startService() method:
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
// Get the service name
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 {
// Get the constructor for the service class
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
// reflection creates a 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); }}Copy the code
Create and start a system service. This system must be com. Android. Server SystemService subclass. Create an example from the reflection of the Class object passed in as the argument, and call the overloaded startService() method:
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
// Call back the system service onStart() method
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");
}
Copy the code
Just two steps. The first step is to register the service. MServices is an ArrayList
object that holds the SystemService that has been created. Step 2, call the onStart() method of the service, again using Installer as an example:
@Override
public void onStart(a) {
if (mIsolated) {
mInstalld = null;
} else{ connect(); }}Copy the code
The service is then started. This is a relatively common startup mode, of course, there are some system services have different startup mode, here is not an analysis, later have the opportunity to analyze the specific service to analyze.
conclusion
The SystemServer startup process is straightforward and not so crooked. Here is a brief summary:
- Language, time zone, and region Settings
- Vm memory Settings
- Fingerprint information, Binder call Settings
Looper.prepareMainLooper()
Create the main thread Looper- Initialize the Native service and load it
libandroid_servers.so
createSystemContext()
To initialize the system context- Create system service management
SystemServiceManager
startBootstrapServices
To start the system boot servicestartCoreServices
To start core system servicesstartOtherServices
To start other servicesLooper.loop()
To start the message loop
In addition, AMS’s onSystemReady() method is called at the end of startOtherServices to start the desktop Activity.
trailer
Remember the Zygote process’s runSelectLoop() method? After creating the system_server process, Zygote silently waits for the client to request to create the application process. In the next article, we will take a look at how the client sends requests, how Zygote handles requests, and how the application process is created from the source point of view. Stay with us!
This article first published wechat official account: BingxinshuaiTM, focusing on Java, Android original knowledge sharing, LeetCode problem solving.
More latest original articles, scan code to pay attention to me!