ActivityThread.main
ActivityThread.main() 是普通 Android 应用 Java 主线程的入口,但它不会直接创建 Application。它先安装进程级 syscall forwarding、用户目录、证书目录和 mainline module,解析 startSeq/deli queue,创建 MainLooper,再构造 ActivityThread 并通过 attachApplication(mAppThread, startSeq) 向 AMS 报到。Application、ContentProvider 和组件生命周期由 AMS 回调后的 handleBindApplication() 才建立。
1. 进程环境
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(
Trace.TRACE_TAG_ACTIVITY_MANAGER,
"ActivityThreadMain");
AndroidForwardingOs.install();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
File configDir = Environment
.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore
.setDefaultUserDirectory(configDir);
initializeMainlineModules();
Process.setArgV0("<pre-initialized>");forwarding OS、CloseGuard、user environment、证书目录和 mainline service managers 都在应用代码执行前设置。进程名暂时改成 <pre-initialized>,真正包名/进程名在 bind application 阶段更新。
2. startSeq关联
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(
PROC_START_SEQ_IDENT.length()));
}
}
}seq=<number> 由 ProcessList 添加,经 Zygote wire protocol 和 RuntimeInit 原样传到 ActivityThread。AMS 用它把 attach 与当前 ProcessRecord 启动请求匹配,避免旧进程迟到的 attach 占用新启动记录。
3. DeliQueue时机
if (args[i].startsWith("--use-deliqueue=")) {
boolean useDeliQueue = Boolean.parseBoolean(
args[i].substring(
args[i].indexOf('=') + 1));
MessageQueue.setUseDeliQueue(useDeliQueue);
}
Looper.prepareMainLooper();deli queue 必须在 prepareMainLooper() 之前设置,因为后者会创建 MessageQueue。该参数来自 platform compat;放错参数顺序或在 Looper 后设置都不会改变已经创建的主队列。
4. 主线程对象
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException(
"Main thread loop unexpectedly exited");ActivityThread 不是 Thread 子类,而是应用主线程状态/消息分发 owner;真正线程就是执行 main 的 Zygote 子进程主线程。mH/main handler 消费 bind application、launch activity、service、receiver、configuration 等消息。Looper.loop() 是正常终点,返回即致命错误。
5. 应用attach
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mConfigurationController =
new ConfigurationController(this);
mSystemThread = system;
mStartSeq = startSeq;
mDdmSyncStageUpdater.next(Stage.Attach);
if (!system) {
DdmHandleAppName.setAppName(
"<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(
mAppThread.asBinder());
IActivityManager mgr =
ActivityManager.getService();
mgr.attachApplication(mAppThread, startSeq);
...
}
}attach 首先发布进程内 current ActivityThread、配置控制器和 startSeq;mAppThread 是 ApplicationThread Binder stub,AMS 后续通过它回调应用。RuntimeInit.setApplicationObject() 让 crash handler 可以向 AMS 报告当前应用 Binder。
6. GC watcher
BinderInternal.addGcWatcher(() -> {
if (!mSomeActivitiesChanged) return;
Runtime runtime = Runtime.getRuntime();
long max = runtime.maxMemory();
long used = runtime.totalMemory()
- runtime.freeMemory();
if (used > (3 * max) / 4) {
mSomeActivitiesChanged = false;
ActivityTaskManager.getService()
.releaseSomeActivities(mAppThread);
}
});GC 后若 activity 状态变化且 Java heap 使用超过 3/4,应用请求 ATM 释放部分 Activity。这个 watcher 不负责触发 GC,也不直接 kill 进程;它是高内存压力下的组件回收消费者。
7. 配置回调
ViewRootImpl.addConfigCallback(
globalConfig -> {
synchronized (mResourcesManager) {
if (mResourcesManager
.applyConfigurationToResources(
globalConfig, null)) {
Configuration updated =
mConfigurationController
.updatePendingConfiguration(
globalConfig);
if (updated != null) {
sendMessage(
H.CONFIGURATION_CHANGED,
globalConfig);
}
}
}
});attach 后注册 ViewRootImpl config callback,先在 ResourcesManager 锁内更新资源,再通过 ActivityThread Handler 投递 configuration changed。资源更新和组件回调分两个阶段,避免 View 层看到旧 Resources。
8. 状态与失败边界
- ActivityThread 对象已创建:不代表 Application 已创建;
attachApplication已发送:不代表 AMS 已回调 bind application;- main Handler 已保存:消息队列已存在,但可能尚无组件;
- RemoteException:system_server 异常,应用 attach 失败并退出;
- startSeq 不匹配:AMS 清理迟到/过期进程;
- Looper 退出:主线程致命状态;
- GC watcher 失败:高内存 Activity 回收链中断,不等于 attach 失败。
9. 导航与后续
# 主入口、环境、参数、Looper 和 attach。
rg -n "public static void main|AndroidForwardingOs|initForCurrentUser|PROC_START_SEQ_IDENT|use-deliqueue|prepareMainLooper|attach\(false|Looper.loop" \
frameworks/base/core/java/android/app/ActivityThread.java
# attach 状态、ApplicationThread Binder、GC watcher 和配置回调。
rg -n "private void attach|setApplicationObject|attachApplication|addGcWatcher|releaseSomeActivities|addConfigCallback|CONFIGURATION_CHANGED" \
frameworks/base/core/java/android/app/ActivityThread.java下一篇将进入 AMS 回调后的 handleBindApplication(),解释 LoadedApk、Instrumentation、ContentProvider、Application 创建和 onCreate 顺序;不会重复主 Looper 和 attach 请求。
