ActivityManagerService Bootstrapping in Android: From SystemServer to Launcher

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: ActivityManager offers a convenient facade for app developers, internally delegating to the proxy.
  • Service-side implementation: ActivityManagerService receives 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:

  1. Starts the SystemUI process via startSystemUi().
  2. Invokes startBootPhase(PHASE_ACTIVITY_MANAGER_READY) so that every SystemService can perform its ready-phase logic.
  3. Calls startHomeOnAllDisplays(), which ultimately uses ActivityStartController to 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.

Tags: Android ActivityManagerService SystemServer Binder Zygote

Posted on Tue, 23 Jun 2026 16:12:17 +0000 by Castle