Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

ActivityThread

ZhangPan edited this page Jul 23, 2025 · 10 revisions

ActivityThread 与主线程 Looper 初始化

ActivityThread 是 Android 程序应用的入口。Java 的 main 方法就在此类中。在 main 方法中会初始化主线程的 Looper。并创建了一个 ActivityThread 示例,调用其 attach 方法。最后通过 Looper.loop 方法开启循环读取 MessageQueue 中的消息。如果 MessageQueue 中没有消息,那么 Looper.loop 方法则一直处于阻塞状态。main 的核心代码如下:

public static void main(String[] args) {
    // ...

    Looper.prepareMainLooper();
    // 初始化ActivityThread
    ActivityThread thread = new ActivityThread();
    // 调用自身的 attach 方法。
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

prepareMainLooper 方法会通过 myLooper 初始化主线程的 Looper,主线程 Looper 是一个位于 Looper 内部的静态成员变量 sMainLooper。

public static void prepareMainLooper() {
    // 初始化 Looper,设置为禁止退出
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

关于 Looper 更多知识参考[Handler 实现原理](https://github.com/zhpanvip/AndroidNote/wiki/Handler%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86)。

ActivityThread 与 Application 的创建

在上一章中,main 方法中会调用 ActivityThread 的构造方法进行初始化,它的构造方法如下:

ActivityThread() {
    // 初始化ResourcesManager
    mResourcesManager = ResourcesManager.getInstance();
}

构造方法初始化了 ResourcesManager 的单利,ResourcesManager 是 APP 的资源管理类,所有的资源文件都是由它来管理的。

接着 main 方法中在 ActivityThread 实例化成功后会调用了自身的 attach 方法,且 attach 方法的参数为 false。attach 方法的核心代码如下:

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        // ...
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        // Watch for getting close to heap limit.
        BinderInternal.addGcWatcher(new Runnable() {
            @Override public void run() {
                if (!mSomeActivitiesChanged) {
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                if (dalvikUsed > ((3*dalvikMax)/4)) {
                    if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                            + " total=" + (runtime.totalMemory()/1024)
                            + " used=" + (dalvikUsed/1024));
                    mSomeActivitiesChanged = false;
                    try {
                        ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
        // ...
    }
    // ...
}

attach 方法中代码可以分为两块:

  1. 设置 GC 监听 这块代码比较简单,通过 BinderInternal.addGcWatcher 方法设置了一个 GC 监听。在监听到 GC 发生时,则判断当前虚拟机使用的内存如果大于总内存的3/4,则尝试回收一些 Activity。
  2. 获取 system_server 中 ActivityManagerService 的代理 ActivityManagerNative.getDefault() 获取到的是 IActivityManager。IActivityManager 是一个 AIDL 类。代码编译后会生成一个 IActivityManager#Stub 类。在系统源码中由 ActivityManagerService 继承了 IActivityManager#Stub。也就是说 IActivityManager 是一个 Binder 类。可以把它看作是 AMS 在客户端的代理。接着通过 IActivityManager 调用 attachApplication 方法,这是一次跨进程的通信。
    // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

在 attachApplication 中又调用了 attachApplicationLocked 方法:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    private void attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        // ...
       
        try {
            // ...
            if (app.getIsolatedEntryPoint() != null) {
                // This is an isolated process which should just call an entry point instead of
                // being bound to an application.
                thread.runIsolatedEntryPoint(
                        app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
            } else {
                // ...

                thread.bindApplication(
                        processName,
                        appInfo,
                        app.sdkSandboxClientAppVolumeUuid,
                        app.sdkSandboxClientAppPackage,
                        isSdkInSandbox,
                        providerList,
                        instrumentationName,
                        profilerInfo,
                        instrumentationArgs,
                        instrumentationWatcher,
                        instrumentationUiConnection,
                        testMode,
                        mBinderTransactionTrackingEnabled,
                        enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode,
                        app.isPersistent(),
                        preBindInfo.configuration,
                        app.getCompat(),
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial,
                        autofillOptions,
                        contentCaptureOptions,
                        app.getDisabledCompatChanges(),
                        app.getLoggableCompatChanges(),
                        serializedSystemFontMap,
                        mApplicationSharedMemoryReadOnlyFd,
                        app.getStartElapsedTime(),
                        app.getStartUptime());
            }

            // ...

            

            // See if the top visible activity is waiting to run in this process...
            if (com.android.server.am.Flags.expediteActivityLaunchOnColdStart()) {
                if (normalMode) {
                    // ActivityTaskManager#LocalService.attachApplication
                    mAtmInternal.attachApplication(app.getWindowProcessController());
                }
            }
            updateOomAdjLocked(app, OOM_ADJ_REASON_PROCESS_BEGIN);
            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");

            if (!mConstants.mEnableWaitForFinishAttachApplication) {
                finishAttachApplicationInner(startSeq, callingUid, pid);
            }
            maybeSendBootCompletedLocked(app, isRestrictedBackupMode);
        } catch (Exception e) {
            // ...
            return;
        }
    }

thread.bindApplication 用于创建 Application,这里的 thread 对象是 ApplicationThread 在 AMS 中的代理对象。这里的bindApplication 方法最终会调用 ApplicationThread.bindApplication 方法,该方法会向 ActivityThread 的消息对应发送BIND_APPLICATION 的消息。消息的处理最终会调用 Application.onCreate 方法,因此 Application 的 onCreate 方法的调用时机比任何Activity 的 onCreate 方法都要早。

public final void bindApplication(String processName, ApplicationInfo appInfo,/**... 省略其它参数**/)
    // ...
    // 通过Handler发送 BIND_APPLICATION 的消息。                         
    sendMessage(H.BIND_APPLICATION, data);
}

在ActivityThread的内部类 H(继承Handler)中的 handleMessage 方法中判断如果是 BIND_APPLICATION 类型的消息则会调用了handleBindApplication(data) 方法。如下:

public void handleMessage(Message msg) {
   
    switch (msg.what) {
        case BIND_APPLICATION:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        // ...
            
    }
}    
private void handleBindApplication(AppBindData data) {
    // ...
  
		// 创建Instrumentation
    if (data.instrumentationName != null) {
        InstrumentationInfo ii = null;
        mInstrumentation.init(this, instrContext, appContext,
               new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
               data.instrumentationUiAutomationConnection);
    } else {
        mInstrumentation = new Instrumentation();
    }

    try {
				// 创建Application
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
        try {
            // 通过Instrumentaion初始化Application
            mInstrumentation.callApplicationOnCreate(app);
        } 
        
        // ...
    } 
    // ...
}

handleBindApplication方法做了简化,这里主要是初始化 Instrumentation,并调用 Instrumentation.callApplicationOnCreate 方法执行 Application 的 onCreate。callApplicationOnCreate 源码如下:

public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

代码很简单,仅仅是调用了Application的onCreate方法,此时,我们项目里边声明的 Application 的 onCreate 方法被调用。

mAtmInternal.attachApplication 用于创建 Activity。实际调用的是 ActivityTaskManager#LocalService.attachApplication。代码如下:

        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                }
                try {
                    // frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java 
                    return mRootWindowContainer.attachApplication(wpc);
                } finally {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        }

又调用 RootWindowContainer 的 attachApplication:

boolean attachApplication(WindowProcessController app) throws RemoteException {
    app.mHasEverAttached = true;
    final ArrayList<ActivityRecord> activities = mService.mStartingProcessActivities;
    RemoteException remoteException = null;
    boolean hasActivityStarted = false;
    for (int i = activities.size() - 1; i >= 0; i--) {
        final ActivityRecord r = activities.get(i);
        if (app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
            // The attaching process does not match the starting activity.
            continue;
        }
        // Consume the pending record.
        activities.remove(i);
        final TaskFragment tf = r.getTaskFragment();
        if (tf == null || r.finishing || r.app != null
                // Ignore keyguard because the app may use show-when-locked when creating.
                || !r.shouldBeVisible(true /* ignoringKeyguard */)
                || !r.showToCurrentUser()) {
            continue;
        }
        try {
            final boolean canResume = r.isFocusable() && r == tf.topRunningActivity();
            if (mTaskSupervisor.realStartActivityLocked(r, app, canResume,
                    true /* checkConfig */)) {
                hasActivityStarted = true;
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception in new process when starting " + r, e);
            remoteException = e;
        }
    }
    if (remoteException != null) {
        throw remoteException;
    }
    return hasActivityStarted;
}

启动第一个页面的 Activity。

ActivityThread 与 Activity 启动

内容见:Activity 的启动流程#再探客户端的调用流程

参考:WMS添加Window过程]

公众号:玩转安卓Dev

Java基础

面向对象与Java基础知识

Java集合框架

JVM

多线程与并发

设计模式

Kotlin

Android

项目相关问题

Android基础知识

Android消息机制

Android Binder

View事件分发机制

Android屏幕刷新机制

View的绘制流程

Activity启动

Framework

性能优化

Jetpack&系统View

第三方框架实现原理

计算机网络

算法

Clone this wiki locally

Morty Proxy This is a proxified and sanitized view of the page, visit original site.