In-depth understanding of AMS
Start the
As mentioned in the Android startup process, AMS is started in system_service,
//frameworks/base/services/java/corri/android/server/SystemServer.java
ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService.
// Set ActivityManagerService to start the sensor service.
startBootstrapServices(); // Start the boot service
// This method is main
BatteryService Is used to count battery power. LightService is required.
// Start the UsageStatsService to collect statistics on application usage.
// Start service WebViewUpdateService.
startCoreServices(); // Start the core service
// This method starts services InputManagerService, WindowManagerService.
// Wait for the ServiceManager and SurfaceFlinger to complete startup. Then the startup screen is displayed.
// Start service StatusBarManagerService,
// Prepare the window, power, package, display service:
// - WindowManagerService.systemReady()
// - PowerManagerService.systemReady()
// - PackageManagerService.systemReady()
// - DisplayManagerService.systemReady()
startOtherServices(); // Start other services
Copy the code
In the startup core service function, AMS is started.
//frameworks/base/services/java/corri/android/server/SystemServer.java
private void startBootstrapServices(a) {...// The ATMS is registered with the ServiceManager and the ATMS start method is called.
ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
// Focus on method 1. Register the AMS service and return the corresponding object information
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
// Set the app installermActivityManagerService.setInstaller(installer); .// Focus on method 2. Register Binder services with the ServiceManager
mActivityManagerService.setSystemProcess();
}
Copy the code
Here we just captured the AMS startup code.
The startService method is used to register and start AMS. Let’s look at the startService method in the specific ActivityManagerService
startService
//
public static ActivityManagerService startService(SystemServiceManager ssm, ActivityTaskManagerService atm) {
sAtm = atm;
// Call SM's startService method. Create an AMS instance and start AMS
return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
}
Copy the code
We explained in the working principle of ServiceManager, systemServiceManager. StartService method corresponding service will be registered to the ServiceManager, then invoke the start method.
//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
serviceClass = (Class<SystemService>)Class.forName(className);
return startService(serviceClass);
}
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
final T service;
try {
// Reflection constructor
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
// Create a serviceservice = constructor.newInstance(mContext); .// Start the service
startService(service);
return service;
} finally{ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); }}public void startService(@NonNull final SystemService service) {
// Register it.
// Register with the ServiceManager list
mServices.add(service);
// Call the onStart method corresponding to the service
service.onStart();
}
Copy the code
When start the AMS incoming parameters are: ActivityManagerService. Lifecycle. The class. So it will actually call ActivityManagerService. The structure of the Lifecycle methods, and then call it onStart method
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
// Create an AMS object
mService = new ActivityManagerService(context, sAtm);
}
@Override
public void onStart(a) {
// call AMS's start method
mService.start();
}
public ActivityManagerService getService(a) {
// an AMS instance is returned
returnmService; }}Copy the code
During the creation of Lifecycle objects, AMS objects are created and started using the start() method.
The AMS to create
The creation of AMS objects is done through constructors.
// select * from ();
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
// Get the ActivityThread for the system
mSystemThread = ActivityThread.currentActivityThread();
// Create a ServiceThread to handle commands received by AMS
mHandlerThread = new ServiceThread(TAG,THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = mInjector.getUiHandler(this);
// Low memory monitoring
mLowMemDetector = new LowMemDetector(this);
// Initialize the broadcast queue. Here includes the foreground broadcast, backstage broadcast and so on
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", foreConstants, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", backConstants, true);
mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler, "offload", offloadConstants, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mBroadcastQueues[2] = mOffloadBroadcastQueue;
// To save the registered Service
mServices = new ActiveServices(this);
//map, which holds the registered ContentProvider
mProviderMap = new ProviderMap(this);
mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);
// Create /data/system directory
final File systemDir = SystemServiceManager.ensureSystemDir();
// Create a process statistics service and save it in the /data/system/proccstats directory.
mProcessStats = new ProcessStatsService(this.new File(systemDir, "procstats"));
// Assign ATM and initialize
mActivityTaskManager = atm;
mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper());
//CPU tracker process
mProcessCpuThread = new Thread("CpuTracker") {
@Override
public void run(a) {... }}; }Copy the code
Some initialization is done in the AMS constructor: starting CPU monitoring, starting the process statistics Service, starting low memory monitoring, initializing the Service and the save classes corresponding to the ContentProvider, and so on.
start()
When the AMS class is created, the start() method is called.
private void start(a) {
// Remove all process groups
removeAllProcessGroups();
// Start the CpuTracker thread
mProcessCpuThread.start();
// Start the battery statistics service, which can count the battery consumption of a specific application, so as to carry out certain battery statistics
mBatteryStatsService.publish();
// Create LocalService and add it to the list of LocalServices
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
mActivityTaskManager.onActivityManagerInternalAdded();
mUgmInternal.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();
}
Copy the code
In the start method, some of the threads created in the constructor are started.
setSystemProcess
After it is created and started, some system-specific services are registered with the ServiceManager using the setSystemProcess method.
public void setSystemProcess(a) {
try {
// Register ActivityService
ServiceManager.addService(Context.ACTIVITY_SERVICE, this./* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
// Register the process status service
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
// Register memory Binder
ServiceManager.addService("meminfo".new MemBinder(this), /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_HIGH);
// Register image Binder
ServiceManager.addService("gfxinfo".new GraphicsBinder(this));
// Register SQLite DB binder
ServiceManager.addService("dbinfo".new DbBinder(this));
if (MONITOR_CPU_USAGE) {
// Register binders for CPU usage
ServiceManager.addService("cpuinfo".new CpuBinder(this),/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
// Register permission control Binder
ServiceManager.addService("permission".new PermissionController(this));
// Register process management Binder
ServiceManager.addService("processinfo".new ProcessInfoService(this));
// Get the ApplicationInfo of the android application and load it to mSystemThread
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
// Create ProcessRecord to maintain information about the process
synchronized (this) { ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,...) ; app.setPersistent(true);
app.pid = MY_PID;
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
mPidsSelfLocked.put(app);
mProcessList.updateLruProcessLocked(app, false.null); updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE); }}catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e); }}Copy the code
This method sets up some system processes. The main functions are:
- Register services: Activity, procSTATS, memInfo, GFXInfo, dbInfo, CPUInfo, Permission, ProcessInfo, and so on.
- Get the ApplicationInfo object of the application whose package name is “Android” and install the ApplicationInfo to SystemThread. Understandably, the system is also a special application.
- Create ProcessRecord to maintain information about the process, where MY_PID is the SystemServer process ID.
- Start monitoring application running and interaction.
subsequent
After AMS is created and launched, there is a series of follow-up work to be done. These operations are invoked in **startOtherServices()**
private void startOtherServices(a) {
// Register the system's ContentProvider information
mActivityManagerService.installSystemProviders();
mActivityManagerService.setWindowManager(wm);
mActivityManagerService.systemReady(() -> {
......//goingCallback
}, BOOT_TIMINGS_TRACE_LOG);
}
Copy the code
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
traceLog.traceBegin("PhaseActivityManagerReady");
synchronized(this) {
// The first entry is false
if (mSystemReady) {
// If AMS is ready, goingCallback's run method is called and returns
if(goingCallback ! =null) {
goingCallback.run();
}
return;
}
mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);
// Call the ATMS onSystemReady method
mActivityTaskManager.onSystemReady();
mSystemReady = true;
}
// Close all processes in procsToKill
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
if(! isAllowedWhileBooting(proc.info)){if (procsToKill == null) {
procsToKill = newArrayList<ProcessRecord>(); } procsToKill.add(proc); }}}synchronized(this) {
if(procsToKill ! =null) {
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
mProcessList.removeProcessLocked(proc, true.false."system update done"); }}// At this point, the entire system is ready. You can create processes and so on.
mProcessesReady = true; }.../ / run goingCallback
if(goingCallback ! =null) goingCallback.run(); .// Start the activity of the Launcher
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); . }}Copy the code
The main functions here are:
- Key services continue to be initialized
- Processes that are already started and do not have the FLAG_PERSISTENT bit will be killed
- Run goingCallBack
- Start the Activity of the launcher, that is, the desktop application.
Here we continue to trace the execution of goingCallBack.
goingCallBack
mActivityManagerService.systemReady(() -> {
try {
// Start NativeCrash monitoring
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
if(! mOnlyCore && mWebViewUpdateService ! =null) {
webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
// Start WebView related
mWebViewUpdateService.prepareWebViewInSystemServer();
}, WEBVIEW_PREPARATION);
}
try {
/ / start systemUI
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e); }... }Copy the code
Some initialization work continues in this:
- Start Native Rash monitoring
- Start webView-related services
- Start the SystemUI
startHomeOnAllDisplays
This function is mainly used to start desktop programs, which is not related to the startup process of AMS. It will not be analyzed in detail here.
Conclusion:
- AMS is created and started in the SystemServer process
- In the process of service startup of AMS, some object creation and initialization are carried out through constructors (at the beginning, the list of other three components and the creation of scheduling objects; Memory, battery, permissions, CPU, etc.) and start services (remove process groups, start CPU threads, permissions registration, battery services, etc.) with the start() method.
- After AMS has created and started the corresponding service, the SystemServer process LoadedApk will be added to the framework-res.apk information through the setSystemProcess method. The SystemServer process ProcessRecord has been added to mPidsSelfLocked, which is managed by AMS
- The rest of the work after AMS starts is performed by calling systemReady() and the incoming goingCallBack. It is mainly a variety of services or processes that need to be further completed after AMS is started and system related initialization.
- The desktop application is started in the systemReady() method and the systemUI is done in the goingCallback.
- When the desktop application has started, the startup broadcast ACTION_BOOT_COMPLETED is sent.
reference
Blog.csdn.net/weixin_3403…
www.cnblogs.com/fanglongxia…
Source code analysis project address: github.com/kailaisi/an…
Synchronous public number [open Ken]