Skip to content

createSystemContext

追踪 ActivityThread.systemMain、system context、SystemUI context、LoadedApk、资源配置与 Perfetto 注册。

基于android-17.0.0_r1
AndroidSystemServerActivityThreadContext源码阅读

createSystemContext ​

SystemServer.createSystemContext() 只有几行,但它建立了后续所有系统服务依赖的 Android 上下文根:ActivityThread.systemMain() 创建系统模式的 ActivityThread 和 Application,getSystemContext() 创建关联系统 LoadedApk 的 ContextImpl,getSystemUiContext() 再创建绑定 display 的 UI context,最后设置主题并注册 Perfetto。它不同于普通应用的 ActivityThread.attach(false, startSeq),也不通过 AMS 注册自己。

1. SystemServer入口 ​

源码文件:frameworks/base/services/java/com/android/server/SystemServer.java

java
private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext =
            activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    Trace.registerWithPerfetto();
}

mSystemContext 是服务编排和大多数 SystemService 的基础 context;systemUiContext 是为系统 UI/display 场景建立的独立包装。二者都使用默认系统主题,但 display 关联和生命周期不同。Trace.registerWithPerfetto() 放在 context 建立后,使后续 SystemServer trace 能使用已准备的系统运行环境。

2. 系统线程 ​

源码文件:frameworks/base/core/java/android/app/ActivityThread.java

java
public static ActivityThread systemMain() {
    ThreadedRenderer.initForSystemProcess();
    ActivityThread thread = new ActivityThread();
    thread.attach(true, 0);
    return thread;
}

SystemServer 先初始化 system process 的 renderer,再创建 ActivityThread,并以 system=true 进入 attach。startSystemServer 之前已由 SystemServer.run() 准备主 Looper,因此 systemMain() 不再调用普通应用的 Looper.prepareMainLooper()。

3. attach的系统分支 ​

源码文件:frameworks/base/core/java/android/app/ActivityThread.java

java
private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mConfigurationController = new ConfigurationController(this);
    mSystemThread = system;
    mStartSeq = startSeq;

    if (!system) {
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        ActivityManager.getService()
                .attachApplication(mAppThread, startSeq);
    } else {
        android.ddm.DdmHandleAppName.setAppName(
                "system_process", UserHandle.myUserId());
        initializeSystemThread(this);
    }
    ViewRootImpl.addConfigCallback(...);
}

普通应用分支通过 Binder 调用 AMS attach;系统分支不调用 attachApplication(),因为 SystemServer 本身承载 AMS 和其他服务。系统分支仍设置 DDM 名称、配置控制器和全局 current ActivityThread,并注册配置变更回调。

4. Application ​

java
private static void initializeSystemThread(
        @NonNull ActivityThread thread) {
    if (!thread.mSystemThread) return;
    try {
        thread.mInstrumentation = new Instrumentation();
        thread.mInstrumentation.basicInit(thread);
        ContextImpl context = ContextImpl.createAppContext(
                thread, thread.getSystemContext().mPackageInfo);
        thread.mInitialApplication = context.mPackageInfo
                .makeApplicationInner(true, null);
        thread.mInitialApplication.onCreate();
    } catch (Exception e) {
        throw new RuntimeException(
                "Unable to instantiate Application()", e);
    }
}

系统 ActivityThread 仍创建 Instrumentation 和 initial Application,但它不是普通 APK 的 Application attach:使用的是 system context 的 LoadedApk,并将 onCreate() 作为 SystemServer context 基础设施的一部分。这里失败会直接阻止 createSystemContext() 返回,服务组尚未开始。

5. SystemContext ​

源码文件:frameworks/base/core/java/android/app/ActivityThread.java、frameworks/base/core/java/android/app/ContextImpl.java

java
public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            mSystemContext =
                    ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}

static ContextImpl createSystemContext(
        ActivityThread mainThread) {
    LoadedApk packageInfo = new LoadedApk(mainThread);
    return createSystemContextInner(mainThread, packageInfo);
}

static ContextImpl createSystemContextInner(
        ActivityThread mainThread, LoadedApk packageInfo) {
    ContextImpl context = new ContextImpl(
            null, mainThread, packageInfo, ...);
    context.setResources(packageInfo.getResources());
    context.mResources.updateConfiguration(
            context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
    return context;
}

getSystemContext() 受 ActivityThread 自身锁保护,懒创建一次。ContextImpl.createSystemContext() 创建新的 LoadedApk,关联 package resources,再把 ResourcesManager 当前 configuration/display metrics 应用到 Context。这个 LoadedApk 是 system context 的资源/类加载 owner;后续 createAppContext() 复用其 package info 构造 initial Application。

6. SystemUI Context ​

源码文件:frameworks/base/core/java/android/app/ActivityThread.java、frameworks/base/core/java/android/app/ContextImpl.java

java
public Context getSystemUiContext(int displayId) {
    synchronized (this) {
        if (mDisplaySystemUiContexts == null) {
            mDisplaySystemUiContexts = new ArrayList<>();
        }
        mDisplaySystemUiContexts.removeIf(
                contextRef -> contextRef.refersTo(null));
        Context context =
                getSystemUiContextNoCreateLocked(displayId);
        if (context != null) return context;
        context = ContextImpl.createSystemUiContext(
                getSystemContext(), displayId);
        mDisplaySystemUiContexts.add(
                new WeakReference<>(context));
        return context;
    }
}

缓存未命中后,真正的 display context 构造发生在 ContextImpl:

java
static Context createSystemUiContext(
        ContextImpl systemContext, int displayId) {
    WindowTokenClient token = new WindowTokenClient();
    ContextImpl context = systemContext
            .createWindowContextBase(token, displayId);
    SystemUiContext systemUiContext =
            new SystemUiContext(context);
    context.setOuterContext(systemUiContext);
    token.attachContext(systemUiContext);
    WindowTokenClientController.getInstance()
            .attachToDisplayContent(token, displayId);
    context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
    return systemUiContext;
}

SystemUI context 按 displayId 缓存 WeakReference,避免 context 永久持有 display UI 对象;创建时基于 system context 派生 window context,通过 WindowTokenClient 绑定 display content。它不是简单复制 mSystemContext,而是有独立 display 配置和 UI 生命周期。

7. 时机与失败定位 ​

createSystemContext() 位于 InitBeforeStartServices,先于 SystemServiceManager 和任何 Bootstrap/Core 服务。失败可按 owner 定位:renderer/ActivityThread attach、Application onCreate、LoadedApk/resources、display token attach 或 Perfetto registration。不要把 mSystemContext 非 null 当作所有系统服务都可用;它只证明基础 Context 已建立。

bash
# SystemServer 入口和主题/Perfetto收尾
rg -n "createSystemContext|DEFAULT_SYSTEM_THEME|registerWithPerfetto" \
  frameworks/base/services/java/com/android/server/SystemServer.java

# systemMain、attach系统分支、system context和SystemUI context
rg -n "systemMain|attach\(boolean system|initializeSystemThread|getSystemContext|getSystemUiContext" \
  frameworks/base/core/java/android/app/ActivityThread.java

# LoadedApk、资源配置和display绑定
rg -n "createSystemContext|createSystemUiContext|createWindowContextBase|attachToDisplayContent|CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI" \
  frameworks/base/core/java/android/app/ContextImpl.java

下一篇将进入 SystemServiceManager 的服务启动分组和生命周期回调;不会重复本文的 ActivityThread、LoadedApk 和 ContextImpl 创建路径。