ActivityThread.H 主线程
应用进程收到系统调度后,并不是 Binder 线程直接调用 Activity 的生命周期方法。Android 17 把远端入口放在 ActivityThread.ApplicationThread,再把事务封装成 Message 投递给 ActivityThread.H;主 Looper 取出消息后,H.handleMessage() 才调用 TransactionExecutor。这条路径把“远程到达”和“主线程执行”分成两个不同阶段。
本文面向已经读过 Handler消息处理、 Handler消息发送、IntentService 请求生命周期 和 HandlerExecutor 提交语义 的读者。本文不 罗列 H 的所有常量,也不重新讲 Activity 的每一个生命周期回调;只沿当前源码的一条主线 回答:谁创建主线程 Handler,Binder 调用如何变成 EXECUTE_TRANSACTION,事务由谁消费, 异常或退出时哪些状态会被清理,以及普通 H 消息与 ClientTransaction 有什么边界。
读完后,读者应能从一个 scheduleTransaction() 入口定位到 H.handleMessage(),解释为什么 生命周期代码在主线程运行,区分 preExecute() 与真正的 execute(),并用测试源码判断事务 执行顺序和失败路径能证明到哪一层。
1. 主线程身份
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
ActivityThread 实例创建时保存当前线程的 Looper,同时创建内部 H 和一个基于该 Handler 的 HandlerExecutor。这里没有创建第二条线程:mH 绑定的是构造它时当前线程的 Looper。
final Looper mLooper = Looper.myLooper();
final H mH = new H();
final Executor mExecutor = new HandlerExecutor(mH);getHandler() 把同一个 mH 暴露给进程内的系统入口;调用方拿到的是主线程 Handler,而不是 一个独立的调度器。
@UnsupportedAppUsage
public Handler getHandler() {
return mH;
}对象边界是:
| 对象 | 所有者 | 消费者 | 作用 |
|---|---|---|---|
ActivityThread | 应用进程主线程 | ApplicationThread、各 handler 方法 | 保存进程级状态 |
mH | ActivityThread | 主 Looper | 把消息分派到 ActivityThread 方法 |
mExecutor | ActivityThread | 需要 Executor 的内部调用 | 复用 mH 的队列 |
mActivities | ActivityThread | 事务执行和生命周期方法 | 保存 Activity token 到本地记录的映射 |
因此,“H 是主线程”更精确的说法是:H 的 mLooper 是主 Looper,H 的消息由主 Looper 串行分发;H 类本身不是线程。
2. 启动循环
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
main() 先准备主 Looper,再创建 ActivityThread、连接系统,最后进入 Looper.loop()。 只有进入循环后,后续通过 mH 入队的消息才有消费者。
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// 解析启动参数和初始化进程环境
Looper.prepareMainLooper();
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");
}这里的异常行不是正常退出分支:主 Looper 正常应持续运行;如果 Looper.loop() 返回,源码把 它视为不符合进程主线程契约的状态。H 的消息生命周期因此依赖三个前置条件:主 Looper 已 准备、ActivityThread 已构造、Looper.loop() 尚未结束。
3. Binder 转发
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
系统进程通过 IApplicationThread 调用应用进程时,Binder 线程进入 ApplicationThread。 以事务为例,Binder 方法不直接执行事务,而是调用外层 ActivityThread.scheduleTransaction()。
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}源码文件:frameworks/base/core/java/android/app/ClientTransactionHandler.java
ActivityThread 继承的 ClientTransactionHandler 负责通用的“预处理再投递”步骤:先调用 事务的 preExecute(),再用 ActivityThread.H.EXECUTE_TRANSACTION 作为消息类型发送。
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}preExecute() 所在的 Binder 线程和之后 TransactionExecutor.execute() 所在的主线程不是 同一个阶段。事务对象可能在预处理阶段准备数据、注册待销毁记录或执行 item 的前置动作, 但 Activity 生命周期的实际消费要等到 H 消息被主 Looper 取出。
这条链路的关键不是“Binder 调 Handler”这一句,而是 preExecute() 与 handleMessage() 之间存在真实的 MessageQueue 边界。消息可能延迟、被队列退出清理,或者在主线程忙碌时等待; Binder 方法返回并不表示 Activity 已经创建或恢复。
4. 消息目录
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
H 用整数常量标识不同的进程级操作,例如绑定应用、创建服务、执行事务、清理资源和退出。 这些常量是协议编号,不是 Java 类型系统;真正的参数类型由 handleMessage() 中每个 case 对 msg.obj 的转换决定。
public static final int BIND_APPLICATION = 110;
public static final int CREATE_SERVICE = 114;
public static final int GC_WHEN_IDLE = 120;
public static final int LOW_MEMORY = 124;
public static final int EXECUTE_TRANSACTION = 159;
public static final int PURGE_RESOURCES = 161;
public static final int SCHEDULE_CRASH = 134;
public static final int EXIT_APPLICATION = 111;codeToString() 只在 DEBUG_MESSAGES 打开时把编号转换为可读名称;关闭调试时返回数字。 因此日志中的 159 是否代表事务,必须结合固定版本的常量表或 codeToString(),不能凭 记忆套用其他 Android 版本的编号。
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
case EXECUTE_TRANSACTION: return "EXECUTE_TRANSACTION";
case PURGE_RESOURCES: return "PURGE_RESOURCES";
case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
}
}
return Integer.toString(code);
}消息目录的学习重点是“编号—payload—消费者”三元组,而不是背下所有常量:
what | msg.obj 形态 | 处理方法 |
|---|---|---|
BIND_APPLICATION | AppBindData | handleBindApplication |
CREATE_SERVICE | CreateServiceData | handleCreateService |
EXECUTE_TRANSACTION | ClientTransaction | mTransactionExecutor.execute |
GC_WHEN_IDLE | 通常无 payload | scheduleGcIdler |
PURGE_RESOURCES | 通常无 payload | schedulePurgeIdler |
5. 事务消费
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
EXECUTE_TRANSACTION case 不直接展开 Activity 的每一个回调,而是把事务交给 mTransactionExecutor。执行前后通知 ClientTransactionListenerController,并用 try/finally 保证“事务结束”通知即使执行器抛异常也会发生。
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
final ClientTransactionListenerController controller =
ClientTransactionListenerController.getInstance();
controller.onClientTransactionStarted();
try {
mTransactionExecutor.execute(transaction);
} finally {
controller.onClientTransactionFinished();
}
break;这里有两个消费者层次:H 消费 Message,TransactionExecutor 消费事务中的 ClientTransactionItem。H 的职责是把协议消息路由到 executor;它不拥有 Activity 生命周期 路径本身。
源码文件:frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
事务执行器会按事务项顺序执行 callbacks,并在需要时执行目标生命周期状态请求。测试源码 将 callback 的顺序作为可观察契约,而不是只验证“某个方法最终被调用”。
public void execute(ClientTransaction transaction) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "clientTransactionExecuted");
try {
executeTransactionItems(transaction);
} catch (Exception e) {
Slog.e(TAG, "Failed to execute the transaction: "
+ transactionToString(transaction, mTransactionHandler));
throw e;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
mPendingActions.clear();
}如果执行某个 item 抛异常,H 的 finally 仍会调用 onClientTransactionFinished(),但后续 事务项是否执行取决于异常是否被上层捕获。finally 只保证 listener 收束,不保证生命周期 事务具有数据库式回滚。
6. 本地路径
源码文件:frameworks/base/core/java/android/app/ClientTransactionHandler.java
同一个抽象类还提供 executeTransaction(),用于本地请求直接执行事务。它设置 mIsExecutingLocalTransaction,调用 preExecute() 和 getTransactionExecutor().execute(), 最后清除标志;这条路径不经过 H 消息。
@VisibleForTesting
public void executeTransaction(ClientTransaction transaction) {
mIsExecutingLocalTransaction = true;
try {
transaction.preExecute(this);
getTransactionExecutor().execute(transaction);
} finally {
mIsExecutingLocalTransaction = false;
}
}因此不能把所有 ClientTransaction 都描述成“先变成 EXECUTE_TRANSACTION 消息”。远程 调度通常走 scheduleTransaction(),本地测试或本地请求可以直接执行。阅读调用方时必须先 确认它调用的是 scheduleTransaction 还是 executeTransaction。
7. 生命周期测试
源码文件:frameworks/base/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
TransactionExecutorTests 不启动完整应用进程,而是用 mock ClientTransactionHandler、 ActivityClientRecord 和生命周期 item,验证状态路径。例如从 ON_CREATE 到 ON_RESUME, 期望经过 ON_START 再到 ON_RESUME。
@Test
public void testLifecycleFromOnCreate() {
mClientRecord.setState(ON_CREATE);
assertArrayEquals(new int[] {}, path(ON_CREATE));
assertArrayEquals(new int[] {ON_START}, path(ON_START));
assertArrayEquals(new int[] {ON_START, ON_RESUME}, path(ON_RESUME));
assertArrayEquals(new int[] {ON_START, ON_RESUME, ON_PAUSE}, path(ON_PAUSE));
}这个测试证明的是 TransactionExecutor 的状态路径推导,不证明真实 H 已经从主队列取出 消息。它把事务消费层从进程启动、Binder 和 MessageQueue 中隔离出来,正好说明本文主线中 “H 路由”和“executor 生命周期算法”是两个可以单独验证的层次。
源码文件:frameworks/base/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
ClientTransactionTests.testPreExecute 建立两个 callback 和一个 lifecycle item,调用 transaction.preExecute(clientTransactionHandler),然后分别验证三个 item 的 preExecute 都收到同一个 handler。
final ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
final ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
doReturn(true).when(stateRequest).isActivityLifecycleItem();
final ClientTransactionHandler clientTransactionHandler =
mock(ClientTransactionHandler.class);
final ClientTransaction transaction = new ClientTransaction();
transaction.addTransactionItem(callback1);
transaction.addTransactionItem(callback2);
transaction.addTransactionItem(stateRequest);
transaction.preExecute(clientTransactionHandler);
verify(callback1).preExecute(clientTransactionHandler);
verify(callback2).preExecute(clientTransactionHandler);
verify(stateRequest).preExecute(clientTransactionHandler);它证明的是 Binder 线程阶段的 item 预处理顺序,不证明 H.handleMessage() 的主线程执行 已经发生。把这两个测试合起来,才能看到 preExecute 与 execute 之间的真实边界。
8. 普通消息
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
并非所有 H 消息都使用 ClientTransaction。例如 GC_WHEN_IDLE 只触发 IdleHandler 注册, PURGE_RESOURCES 只调度资源清理,REMOVE_PROVIDER 则是带延迟的普通 Message。
case GC_WHEN_IDLE:
scheduleGcIdler();
break;
case PURGE_RESOURCES:
schedulePurgeIdler();
break;
case REMOVE_PROVIDER:
completeRemoveProvider((ProviderRefCount) msg.obj);
break;这解释了为什么 H 不能被概括成“Activity 生命周期 Handler”:它还是应用进程级的统一 入口,承载 Provider、资源、GC、广播、Service 和调试命令等不同协议。文章选择 EXECUTE_TRANSACTION 作为主线,是为了讲清一条完整调用链,不是声称其他 case 都走同一 executor。
9. 延迟清理
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
Provider 引用释放时,ActivityThread 把真正移除延迟到 CONTENT_PROVIDER_RETAIN_TIME 之后, 消息的 obj 保存 ProviderRefCount。消息到达时 completeRemoveProvider() 先再次检查 removePending,以处理延迟期间 provider 被重新获取的竞态。
if (lastRef) {
if (!prc.removePending) {
prc.removePending = true;
Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
mH.sendMessageDelayed(msg, CONTENT_PROVIDER_RETAIN_TIME);
} else {
Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
}
}消息到达后,消费者还要在 provider 引用表锁内重新确认是否仍然允许移除:
void completeRemoveProvider(ProviderRefCount prc) {
synchronized (mProviderMap) {
if (!prc.removePending) {
// A client acquired the provider again before removal completed.
return;
}
prc.removePending = false;
// 从 provider 引用表和 provider map 中移除
}
}这是 H 消息“成功到达但不一定执行原计划”的一个具体例子:延迟消息只是触发再次检查, completeRemoveProvider 的状态判断决定清理是否真的生效。取消或恢复逻辑属于消费者状态, 不是 MessageQueue 的时间排序自动提供的。
10. 消息异常
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
handleMessage() 对不同 case 采用不同异常边界。有些 case 用 try/finally 结束 Trace, 有些 case 直接调用处理方法;EXECUTE_TRANSACTION 额外用 listener 的 finally,但没有把 所有异常转换为普通返回值。
case RECEIVER:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
}
ReceiverData receiverData = (ReceiverData) msg.obj;
try {
handleReceiver(receiverData);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;事务 case 的清理对象不同:它围绕 ClientTransactionListenerController 建立执行边界。
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
final ClientTransactionListenerController controller =
ClientTransactionListenerController.getInstance();
controller.onClientTransactionStarted();
try {
mTransactionExecutor.execute(transaction);
} finally {
controller.onClientTransactionFinished();
}
break;Trace 收尾和事务 listener 收尾是“清理动作”,不是异常恢复。若生命周期 item 抛出异常, 外层 Looper 的异常策略仍然参与;不能因为看到 finally 就推导出应用会继续处理下一条消息。
11. 退出消息
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
EXIT_APPLICATION 的 case 先调用 Application.onTerminate()(如果存在初始 Application), 然后让当前 Looper 退出。这个路径说明 H 既能驱动业务生命周期,也能结束自身的消息消费者。
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;这不是所有异常的通用清理路径。进程被 SUICIDE 或 native 级终止路径结束时,可能没有机会 走 EXIT_APPLICATION;而主 Looper 退出后,后续发送给 mH 的消息也不能获得正常消费者。
12. 事务监听
源码文件:frameworks/base/core/java/android/app/servertransaction/ClientTransactionListenerController.java
H 在事务前后通知 listener controller,controller 负责把事务期间发生的配置变化等事件 延后到事务完成后再处理。测试专门覆盖“事务进行中不立即触发,事务结束后才触发”的顺序。
public void onClientTransactionStarted() {
synchronized (mLock) {
mIsClientTransactionExecuting = true;
}
}
public void onClientTransactionFinished() {
synchronized (mLock) {
mIsClientTransactionExecuting = false;
// 收集事务期间延后的配置变化
}
// 锁外派发 display changed callbacks
}源码文件:frameworks/base/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
mController.onClientTransactionStarted();
mController.onContextConfigurationPreChanged(mActivity);
mConfiguration.windowConfiguration.setMaxBounds(new Rect(0, 0, 100, 200));
mController.onContextConfigurationPostChanged(mActivity);
verify(mController, never()).onDisplayChanged(anyInt());
mController.onClientTransactionFinished();
verify(mController).onDisplayChanged(123);这里的测试输入不是直接测试 Handler,而是测试 H 的 finally 所保护的事务边界消费者。 它能证明 listener 的延后顺序,不能证明所有 Activity 生命周期回调都被该 controller 监听。
13. 复查命令
源码文件:
frameworks/base/core/java/android/app/ActivityThread.javaframeworks/base/core/java/android/app/ClientTransactionHandler.javaframeworks/base/core/java/android/app/servertransaction/TransactionExecutor.javaframeworks/base/core/java/android/app/servertransaction/ClientTransactionListenerController.javaframeworks/base/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.javaframeworks/base/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.javaframeworks/base/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
rg -n "final H mH|class H extends Handler|getHandler\(\)|prepareMainLooper|Looper.loop" \
frameworks/base/core/java/android/app/ActivityThread.java
rg -n "scheduleTransaction|preExecute|EXECUTE_TRANSACTION|executeTransaction" \
frameworks/base/core/java/android/app/ClientTransactionHandler.java \
frameworks/base/core/java/android/app/ActivityThread.java
rg -n "case EXECUTE_TRANSACTION|onClientTransactionStarted|mTransactionExecutor.execute" \
frameworks/base/core/java/android/app/ActivityThread.java
rg -n "testPreExecute|testLifecycleFromOnCreate|onClientTransactionStarted" \
frameworks/base/core/tests/coretests/src/android/app/servertransaction复述主线时,至少要区分:Binder 线程的 preExecute()、主线程的 H.handleMessage()、 TransactionExecutor 的 item 执行,以及 listener finally 的结束通知。把它们压缩成“AMS 发消息,ActivityThread 执行生命周期”会丢失最重要的线程和状态边界。
14. 适用边界
ActivityThread.H 是应用进程主 Looper 上的协议分派器,不是通用业务 Handler,也不是所有 生命周期算法的 owner。它负责将整数 what 和 payload 路由到 ActivityThread 的处理方法; 事务顺序、Activity 状态路径、Provider 延迟清理和 IdleHandler 清理分别由各自消费者维护。
当排查“系统调用已到达但 Activity 尚未变化”时,按源码顺序检查:Binder 是否进入 ApplicationThread,事务是否完成 preExecute(),EXECUTE_TRANSACTION 是否成功入队,主 Looper 是否取出消息,TransactionExecutor 是否在 item 处抛异常,以及 listener/清理状态是否 改变了后续观察。这样才能把远端到达、主线程排队、事务执行和最终 UI 状态区分开。
