AMS全流程深度解析

346 阅读7分钟

一、zygote进程的启动与初始化

1. init进程触发zygote启动

  • 核心机制

    由Linux内核首个用户进程`init`解析`init.rc`脚本启动Zygote:
    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 
    class main
    socket zygote stream 660 root system
       关键参数`--start-system-server`触发SystemServer进程的创建
       首先解释一下这里面的代码,他们分别是干什么的,
       1.定义一个名为 `zygote` 的系统服务。
       
       `zygote` 是 Android 的核心服务,负责孵化(fork)新的应用进程。
       `/system/bin/app_process` 是 Zygote 的可执行文件路径。
        `-Xzygote /system/bin`:传递给 `app_process` 的 JVM 参数(设置 Zygote 的启动路径)。
       `--zygote`:标志位,表示启动 Zygote 进程。
       `--start-system-server`:启动后立即创建 System Server 进程(如 `ActivityManagerService` 等核心系统服务)。
       
       2. ​**​`class main`​**​
         指定该服务属于 `main` 类。
        `main` 是 Android 中预定义的服务类别,系统启动时会通过 `class_start main` 命令启动所有属于 `main` 类的服务。其他可能的类名包括 `core`(更早启动的服务)或自定义类别。
    
      3. ​**​`socket zygote stream 660 root system`​**​
           为 Zygote 服务创建一个 Unix Domain Socket。
        `socket zygote`:定义 Socket 名称为 `zygote``stream`:Socket 类型为流式(可靠的双向字节流,类似 TCP)。
         `660`:文件权限(`rw-rw----`),即拥有者和所属组有读写权限,其他用户无权限。
        `root system`:Socket 的拥有者为 `root` 用户,所属组为 `system` 组。
       ​**​用途​**​:Zygote 通过此 Socket 接收来自系统或应用的请求(例如启动新应用进程)。
       
       
    
  • Zygote预加载机制

1.Zygote 在启动时会预加载公共类库、资源和 JNI 库,所有子进程(如 App 进程)共享这些预加载内容,避免重复加载,提高效率。(frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

图片.png

如上关键代码解释:

  • preloadClasses()​:
    /system/etc/preloaded-classes 文件读取需要预加载的类列表(如 core-libart.jarframework.jar 中的类)。
    该文件由编译系统生成,包含所有标记为 preloaded 的类。

  • preloadResources()​:
    加载 framework-res.apk 中的资源(如布局、主题、字符串),避免每个 App 单独加载

  • nativePreloadAppProcessHAL()​:
    通过 JNI 调用加载系统核心 JNI 库

2.copy-on-write

Zygote 通过 Linux 的 ​fork()​ 机制创建子进程,所有子进程共享 Zygote 的只读内存页。当子进程尝试修改内存时,会触发 ​​写时复制​​,复制一份新内存页供子进程使用。

核心代码如下:

图片.png

2.启动SystemServer进程

Zygote 在启动后,会创建第一个子进程 SystemServer,它是所有系统服务的宿主(如 ActivityManagerServicePackageManagerService)。

  • 启动流程代码

    核心代码如下:ZygoteInit.java 中的main方法

@UnsupportedAppUsage
public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;

    // Mark zygote start. This ensures that thread creation will throw
    // an error.
    ZygoteHooks.startZygoteNoThreadCreation();

    // Zygote goes into its own process group.
    try {
        Os.setpgid(0, 0);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to setpgid(0,0)", ex);
    }

    Runnable caller;
    try {
        // Store now for StatsLogging later.
        final long startTime = SystemClock.elapsedRealtime();
        final boolean isRuntimeRestarted = "1".equals(
                SystemProperties.get("sys.boot_completed"));

        String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
        TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                Trace.TRACE_TAG_DALVIK);
        bootTimingsTraceLog.traceBegin("ZygoteInit");
        RuntimeInit.preForkInit();

        boolean startSystemServer = false;
        String zygoteSocketName = "zygote";
        String abiList = null;
        boolean enableLazyPreload = false;
        for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {
                startSystemServer = true;
            } else if ("--enable-lazy-preload".equals(argv[i])) {
                enableLazyPreload = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }

        final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
        if (!isRuntimeRestarted) {
            if (isPrimaryZygote) {
                FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                        BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,
                        startTime);
            } else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {
                FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                        BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,
                        startTime);
            }
        }

        if (abiList == null) {
            throw new RuntimeException("No ABI list supplied.");
        }

        // In some configurations, we avoid preloading resources and classes eagerly.
        // In such cases, we will preload things prior to our first fork.
        if (!enableLazyPreload) {
            bootTimingsTraceLog.traceBegin("ZygotePreload");
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
            preload(bootTimingsTraceLog);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
            bootTimingsTraceLog.traceEnd(); // ZygotePreload
        }

        // Do an initial gc to clean up after startup
        bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
        gcAndFinalize();
        bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

        bootTimingsTraceLog.traceEnd(); // ZygoteInit

        Zygote.initNativeState(isPrimaryZygote);

        ZygoteHooks.stopZygoteNoThreadCreation();

        zygoteServer = new ZygoteServer(isPrimaryZygote);

        if (startSystemServer) {
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");

        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with fatal exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}

​关键步骤​​:

  1. ​参数检查​​:
    启动 Zygote 时传入 --start-system-server 参数(见 init.rc 中的服务定义),触发 forkSystemServer()

  2. ​调用 fork()​:
    通过 Zygote.forkSystemServer() 调用底层 fork(),创建子进程。

  3. ​子进程初始化​​:
    子进程(SystemServer)执行 handleSystemServerProcess(),最终调用 SystemServer.main()

  • SystemServer 入口代码

    frameworks/base/services/java/com/android/server/SystemServer.java 核心代码:

//入口
public static void main(String[] args) {
    new SystemServer().run();
}
```
 private void run() {
        // 1. 初始化系统上下文
        createSystemContext();  // 使用 Zygote 预加载的类库和资源
        
        // 2. 启动引导服务(ActivityManagerService、PowerManagerService 等)
        startBootstrapServices();
        
        // 3. 启动核心服务(BatteryService、UsageStatsService 等)
        startCoreServices();
        
        // 4. 启动其他服务(WindowManagerService、InputManagerService 等)
        startOtherServices();
    }
```
  • ​继承 Zygote 的预加载资源​​:
    由于 SystemServer 是 Zygote 的子进程,直接共享 Zygote 预加载的类、资源和 JNI 库,无需重新加载。

  • ​系统服务初始化​​:
    SystemServer 依次启动所有系统服务,例如 ActivityManagerService 的启动代码:

二、AMS启动与初始化

​1. SystemServer启动AMS​
  • 启动入口

    SystemServer.startBootstrapServices()中调用:代码如下:

ActivityTaskManagerService atm = mSystemServiceManager.startService(
        ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
        mSystemServiceManager, atm);
​2. AMS构造函数核心操作​
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
    LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
    mInjector = new Injector(systemContext);
    mContext = systemContext;

    mFactoryTest = FactoryTest.getMode();
    mSystemThread = ActivityThread.currentActivityThread();
    mUiContext = mSystemThread.getSystemUiContext();

    Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());

    mHandlerThread = new ServiceThread(TAG,
            THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
    mHandlerThread.start();
    mHandler = new MainHandler(mHandlerThread.getLooper());
    mUiHandler = mInjector.getUiHandler(this);

    mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
            THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
    mProcStartHandlerThread.start();
    mProcStartHandler = new ProcStartHandler(this, mProcStartHandlerThread.getLooper());

    mConstants = new ActivityManagerConstants(mContext, this, mHandler);
    final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
    mPlatformCompat = (PlatformCompat) ServiceManager.getService(
            Context.PLATFORM_COMPAT_SERVICE);
    mProcessList = mInjector.getProcessList(this);
    mProcessList.init(this, activeUids, mPlatformCompat);
    mAppProfiler = new AppProfiler(this, BackgroundThread.getHandler().getLooper(),
            new LowMemDetector(this));
    mPhantomProcessList = new PhantomProcessList(this);
    mOomAdjuster = mConstants.ENABLE_NEW_OOMADJ
            ? new OomAdjusterModernImpl(this, mProcessList, activeUids)
            : new OomAdjuster(this, mProcessList, activeUids);

    mEnableOffloadQueue = SystemProperties.getBoolean(
            "persist.device_config.activity_manager_native_boot.offload_queue_enabled", true);
    mEnableModernQueue = new BroadcastConstants(
            Settings.Global.BROADCAST_FG_CONSTANTS).MODERN_QUEUE_ENABLED;

    mBroadcastQueues = mInjector.getBroadcastQueues(this);

    mServices = new ActiveServices(this);
    mCpHelper = new ContentProviderHelper(this, true);
    mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
    mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);
    mUidObserverController = new UidObserverController(mUiHandler);

    final File systemDir = SystemServiceManager.ensureSystemDir();

    // TODO: Move creation of battery stats service outside of activity manager service.
    mBatteryStatsService = BatteryStatsService.create(systemContext, systemDir,
            BackgroundThread.getHandler(), this);
    mOnBattery = DEBUG_POWER ? true
            : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
    mOomAdjProfiler.batteryPowerChanged(mOnBattery);

    mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));

    mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops_accesses.xml"),
            new File(systemDir, "appops.xml"), mHandler);

    mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);

    mUserController = new UserController(this);
    mInjector.mUserController = mUserController;

    mPendingIntentController = new PendingIntentController(
            mHandlerThread.getLooper(), mUserController, mConstants);

    mAppRestrictionController = new AppRestrictionController(mContext, this);

    mUseFifoUiScheduling = SystemProperties.getInt("sys.use_fifo_ui", 0) != 0;

    mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
    mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);

    mActivityTaskManager = atm;
    mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,
            DisplayThread.get().getLooper());
    mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);

    mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);

    Watchdog.getInstance().addMonitor(this);
    Watchdog.getInstance().addThread(mHandler);

    // bind background threads to little cores
    // this is expected to fail inside of framework tests because apps can't touch cpusets directly
    // make sure we've already adjusted system_server's internal view of itself first
    updateOomAdjLocked(OOM_ADJ_REASON_SYSTEM_INIT);
    try {
        Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
                Process.THREAD_GROUP_SYSTEM);
        Process.setThreadGroupAndCpuset(
                mOomAdjuster.mCachedAppOptimizer.mCachedAppOptimizerThread.getThreadId(),
                Process.THREAD_GROUP_SYSTEM);
    } catch (Exception e) {
        Slog.w(TAG, "Setting background thread cpuset failed");
    }

    mInternal = new LocalService();
    mPendingStartActivityUids = new PendingStartActivityUids();
    mTraceErrorLogger = new TraceErrorLogger();
    mComponentAliasResolver = new ComponentAliasResolver(this);
}

Lifecycle.onStart()中调用publishBinderService(),向ServiceManager注册activity服务

​systemReady()调用链​​:

mActivityManagerService.systemReady(() -> { startHomeActivityLocked(); // 启动Launcher });

此时完成权限检查、服务依赖初始化,触发首Activity启动

​三、Launcher启动与Activity触发​

源码位置:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

​核心流程​​:

Intent 构建: 此处开始触发Activity调用

Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

ActivityStack管理​​:

创建ActivityRecord并压入前台栈(mFocusedStack

启动流程​

void setFocusedTask(int taskId, ActivityRecord touchedActivity) {
    ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedTask: taskId=%d touchedActivity=%s", taskId,
            touchedActivity);
    final Task task = mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_ONLY);
    if (task == null) {
        return;
    }
    final ActivityRecord r = task.topRunningActivityLocked();
    if (r == null) {
        return;
    }

    if ((touchedActivity == null || r == touchedActivity) && r.isState(RESUMED)
            && r == mRootWindowContainer.getTopResumedActivity()) {
        setLastResumedActivityUncheckLocked(r, "setFocusedTask-alreadyTop");
        return;
    }
    final Transition transition = (getTransitionController().isCollecting()
            || !getTransitionController().isShellTransitionsEnabled()) ? null
            : getTransitionController().createTransition(TRANSIT_TO_FRONT);
    if (transition != null) {
        // Set ready before doing anything. If order does change, then that will set it unready
        // so that we wait for the new lifecycles to complete.
        transition.setReady(task, true /* ready */);
    }
    final boolean movedToTop = r.moveFocusableActivityToTop("setFocusedTask");
    if (movedToTop) {
        if (transition != null) {
            getTransitionController().requestStartTransition(
                    transition, null /* startTask */, null /* remote */, null /* display */);
        }
        mRootWindowContainer.resumeFocusedTasksTopActivities();
    } else if (touchedActivity != null && touchedActivity.isFocusable()) {
        final TaskFragment parent = touchedActivity.getTaskFragment();
        if (parent != null && parent.isEmbedded()) {
            // Set the focused app directly if the focused window is currently embedded
            final DisplayContent displayContent = touchedActivity.getDisplayContent();
            displayContent.setFocusedApp(touchedActivity);
            mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
                    true /* updateInputWindows */);
        }
    }
    if (transition != null && !movedToTop) {
        // No order changes and focus-changes, alone, aren't captured in transitions.
        transition.abort();
    }
}

​四、应用进程创建与ActivityThread初始化​

​1.进程创建请求​​:

frameworks/base/services/core/java/com/android/server/am/ProcessList.java

源码入口:ActivityManagerService.startProcessLocked()

关键函数:

startResult = Process.start(entryPoint,
        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
        isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
        allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
        bindOverrideSysprops,
        new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});

图片.png

如上函数,目的是 通过Socket向Zygote发送fork请求

2.Zygote响应与进程初始化​​:

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

private Runnable handleChildProc(ZygoteArguments parsedArgs,
        FileDescriptor pipeFd, boolean isZygote) {
    /*
     * By the time we get here, the native code has closed the two actual Zygote
     * socket connections, and substituted /dev/null in their place.  The LocalSocket
     * objects still need to be closed properly.
     */

    closeSocket();

    Zygote.setAppProcessName(parsedArgs, TAG);

    // End of the postFork event.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (parsedArgs.mInvokeWith != null) {
        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.mRemainingArgs);

        // Should not get here.
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(
                    parsedArgs.mRemainingArgs  /* classLoader */);
        }
    }
}

ActivityThread主线程启动​​:

源码入口​​:ActivityThread.main()

关键操作​​:

  • 创建主线程Looper(Looper.prepareMainLooper()
  • 绑定到AMS(attach() -> AMS.attachApplication()

​五、Activity生命周期与UI绘制​

​Activity启动回调​​: 源码入口​​:ActivityThread.handleLaunchActivity()

位置​​:frameworks/base/core/java/android/app/ActivityThread.java

@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }

    // Make sure we are running with the most recent config and resource paths.
    applyPendingApplicationInfoChanges(r.activityInfo.packageName);
    mConfigurationController.handleConfigurationChanged(null, null);
    updateDeviceIdForNonUIContexts(deviceId);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    if (ThreadedRenderer.sRendererEnabled
            && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
        HardwareRenderer.preload();
    }
    WindowManagerGlobal.initialize();

    // Hint the GraphicsEnvironment that an activity is launching on the process.
    GraphicsEnvironment.hintActivityLaunch();

    final Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfigurationController.getConfiguration());
        reportSizeConfigurations(r);
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
                null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
    }

    return a;
}

​UI绘制流程​​:

​ViewRootImpl初始化​​:

(这个专题在后面会结合 SurfaceFlinger 一起讲解)

至此,AMS流程基本结束,在梳理整个AMS的过程中,有几个延伸的点,我将大纲列在下面,大家感兴趣的可以去阅读后面的博客

--Binder IPC机制详解

AMS调度策略

Activity栈管理 -- 多窗口模式

ANR机制分析

启动性能优化