The ActivityManagerService (AMS) is one of the core system services that orchestrate application component lifecycles, process management, and task scheduling. Understanding its initialization path reveals how Android’s runtime scaffolding is assembled before any user app appears. This article traces the AMS startup sequence from the kernel’s first user-space process down to the moment Launcher is displayed.
Boot Prerequisites: init → zygote → system_server
When an Android device powers on, the bootloader loads the Linux kernel, which spawns the init process (PID 1). Init parses init.rc scripts and launches the Zygote process. Zygote then forks the system_server process, where virtually all high-level Android services—including AMS, WindowManagerService, PackageManagerService, and PowerManagerService—are hosted.
What Exactly Is AMS?
AMS is a Java class extending IActivityManager.Stub, making it a Binder server. It exposes an IPC interface that both the framework and third-party apps use to request activity starts, service bindings, broadcast delivery, and content provider access. Because it lives inside system_server, AMS has direct access to privileged APIs and can coordinate with other system services.
Key architectural pieces surrounding AMS:
- Proxy layer:
ActivityManagerNative(generated by AIDL) provides proxy objects for remote calls. - Client helper:
ActivityManageroffers a convenient facade for app developers, internally delegating to the proxy. - Service-side implementation:
ActivityManagerServicereceives Binder transactions and processes them on dedicated handler threads.
The SystemServer Run Loop
Once system_server starts, its main() method calls SystemServer.run(). This method guides the entire service bootstrap through three main phases:
public final class SystemServer {
private void run() {
// ...
createSystemContext();
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
// ...
}
}
1. createSystemContext() – Building the System’s Context
AMS requires resources and a Context object for loading drawables, strings, and configuration data. createSystemContext() sets up the very first ContextImpl for the system process:
private void initSystemContext() {
ActivityThread thread = ActivityThread.systemMain();
mSystemContext = thread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
// System UI context is also prepared
Context uiCtx = thread.getSystemUiContext();
uiCtx.setTheme(DEFAULT_SYSTEM_THEME);
}
Under the hood, ActivityThread.systemMain() constructs a new ActivityThread for the system process, calls attach(true) to create Instrumentation and a base Application, and then retrieves the system-level ContextImpl backed by a LoadedApk entry representing the android package. This context is later used to resolve system resources like @android:drawable/ic_menu_gallery.
2. startBootstrapServices() – Instantiating AMS
This phase brings up foundational services that other components depend on. The AMS is created through a Lifecycle indirection:
ActivityTaskManagerService atm = systemServiceMgr.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
ActivityManagerService ams = ActivityManagerService.Lifecycle.startService(
systemServiceMgr, atm);
ActivityManagerService.Lifecycle extends SystemService and holds the actual AMS instance. Its constructor is called reflectively by SystemServiceManager:
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context ctx) {
super(ctx);
mService = new ActivityManagerService(ctx, sAtm);
}
public ActivityManagerService getService() {
return mService;
}
}
This pattern gives AMS a well-defined lifecycle phase callback (onBootPhase()), enabling it to react to events like PHASE_SYSTEM_SERVICES_READY or PHASE_THIRD_PARTY_APPS_CAN_START.
3. Inside the AMS Constructor
When new ActivityManagerService(context, atm) executes, several critical subcomponents are initialized:
public ActivityManagerService(Context sysCtx, ActivityTaskManagerService atm) {
mContext = sysCtx;
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
// Foreground handler for operations that shouldn't be blocked
ServiceThread handlerThread = new ServiceThread("ActivityManager",
THREAD_PRIORITY_FOREGROUND, false);
handlerThread.start();
mHandler = new MainHandler(handlerThread.getLooper());
// Process lifecycle management
mProcessList = new ProcessList(this);
// Broadcast queues for foreground, background, and offloaded broadcasts
BroadcastConstants fgConstants = new BroadcastConstants(...);
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", fgConstants, false);
// ... similar for bg / offload queues
// ActiveServices - the controller of Service and registered broadcast receivers
mServices = new ActiveServices(this);
// Content provider helper
mCpHelper = new ContentProviderHelper(this, true);
// Battery and process stats
mBatteryStatsService = new BatteryStatsService(sysCtx, systemDir, ...);
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
mActivityTaskManager = atm;
mActivityTaskManager.initialize(mIntentFirewall, ...);
// ...
}
The constructor also registers itself with Watchdog and adjusts thread groups. Notably, ActiveServices is the engine behind managing bound services, service restarts, and connection records—AMS delegates most service-related logic to it.
4. startCoreServices() and startOtherServices()
After bootstrap services are up, the system spins up core and other services like BatteryService, UsageStatsService, NotificationManagerService, and WindowManagerService. AMS is interwoven with these via setter methods:
// from startOtherServices()
ams.installSystemProviders(); // system content providers
ams.setWindowManager(windowManager); // associates WindowManagerService
ams.systemReady(); // final preparation before launching home
Publishing AMS as a System Service
In setSystemProcess(), AMS registers itself and several helper sevrices with the native ServiceManager (the C/C++ binder service registry):
public void registerServices() {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true, DUMP_FLAG_CRITICAL);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
ServiceManager.addService("permission", new PermissionController(this));
// ...
}
This is why commands like adb shell dumpsys activity work—they reach AMS through the registered service handle.
Final Boot Phase: systemReady and Launcher
When ams.systemReady() is called, all ~80+ services have finished initializing. The system then:
- Starts the SystemUI process via
startSystemUi(). - Invokes
startBootPhase(PHASE_ACTIVITY_MANAGER_READY)so that everySystemServicecan perform its ready-phase logic. - Calls
startHomeOnAllDisplays(), which ultimately usesActivityStartControllerto bring up the Launcher activity.
private void launchHome(int userId) {
Intent homeIntent = mHomeIntent; // Intent with CATEGORY_HOME
ActivityInfo aInfo = resolveHomeIntent(homeIntent);
// ... start activity through ActivityStarter
}
At this point, the user sees the home screen, and AMS is fully operational, ready to manage foreground/background processes, deliver broadcasts, and enforce priorities while the device runs.