news 2026/8/9 5:46:20

为什么说ActivityThread是主线程?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么说ActivityThread是主线程?

这是一个非常经典的问题。要理解这一点,必须从Android 应用进程的启动机制消息循环模型两个维度来拆解。


一、先说结论:ActivityThread 不是线程,但主线程的"灵魂"是它

ActivityThread的类定义是:

java

public final class ActivityThread { // 注意:它并没有 extends Thread }

它本身不是java.lang.Thread的子类,但为什么说它是主线程的实际管理者

因为:

  1. 应用进程的入口ActivityThread.main()方法

  2. main()方法中创建了主线程的 Looper 并启动消息循环

  3. 主线程的所有工作(生命周期、UI 更新、事件处理)都是通过ActivityThread内部的 Handler 分发的

所以,ActivityThread主线程逻辑的载体,主线程的"肉体"是 Linux 的 UI 线程,"灵魂"是ActivityThread管理的消息循环和调度逻辑。


二、体现在哪里?逐层详解

1. 应用进程入口:main() 方法

当你点击 App 图标时,Zygote 进程 fork 出新的应用进程,新进程的入口不是Application.onCreate(),而是:

java

// android.app.ActivityThread // Android 框架约定:这条初始线程负责 UI 绘制、事件分发、生命周期回调,因此它被称为"主线程"(Main Thread)或"UI 线程" public static void main(String[] args) { // 1. 准备主线程的 Looper Looper.prepareMainLooper(); // 2. 创建 ActivityThread 实例 ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); // 3. 获取主线程的 Handler(即 H) if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } // 4. 开启消息循环,阻塞在这里,直到进程死亡 Looper.loop(); // 5. 如果 loop 退出,抛异常(主线程不允许退出) throw new RuntimeException("Main thread loop unexpectedly exited"); }

关键体现

  • Looper.prepareMainLooper():为主线程创建唯一的LooperMessageQueue

  • Looper.loop():主线程进入无限循环,不断从消息队列取消息执行

  • 这个main()方法跑在应用进程的主线程上,所以ActivityThread是主线程的"入口管理者"


2. 主线程的消息分发中心:内部类 H

ActivityThread内部定义了一个名为H的 Handler(源码中真的叫H):

java

// ActivityThread.java class H extends Handler { public static final int LAUNCH_ACTIVITY = 100; public static final int PAUSE_ACTIVITY = 101; public static final int STOP_ACTIVITY_SHOW = 103; public static final int RESUME_ACTIVITY = 107; public static final int DESTROY_ACTIVITY = 109; public static final int BIND_APPLICATION = 110; public static final int EXIT_APPLICATION = 111; public static final int RECEIVER = 113; public static final int CREATE_SERVICE = 114; public static final int SERVICE_ARGS = 115; public static final int STOP_SERVICE = 116; public static final int CONFIGURATION_CHANGED = 118; // ... 还有几十种消息类型 public void handleMessage(Message msg) { switch (msg.what) { case LAUNCH_ACTIVITY: { // 处理 Activity 创建 handleLaunchActivity((ActivityClientRecord) msg.obj); break; } case PAUSE_ACTIVITY: { // 处理 Activity 暂停 handlePauseActivity((ActivityClientRecord) msg.obj); break; } case RESUME_ACTIVITY: { // 处理 Activity 恢复 handleResumeActivity((ActivityClientRecord) msg.obj); break; } case DESTROY_ACTIVITY: { // 处理 Activity 销毁 handleDestroyActivity((ActivityClientRecord) msg.obj); break; } // ... } } }

关键体现

  • 主线程的所有跨进程指令(来自 AMS)最终都变成Message,被H接收

  • H.handleMessage()在主线程执行,进而调用handleLaunchActivityhandleResumeActivity

  • 这些handleXxx方法内部会调用Instrumentation,最终触发Activity.onCreate()onResume()等生命周期方法

所以你的onCreate()本质上是这样被执行的

plain

AMS (系统进程) ↓ Binder 调用 ApplicationThread (应用进程 Binder 对象) ↓ 发送 Message H (主线程 Handler) ↓ handleMessage handleLaunchActivity() ↓ Instrumentation.callActivityOnCreate() ↓ Activity.performCreate() ↓ 你的 Activity.onCreate()

3. 与系统服务通信的桥梁:ApplicationThread

ActivityThread内部持有ApplicationThread,它是一个Binder对象:

java

// ActivityThread.java private class ApplicationThread extends IApplicationThread.Stub { // AMS 通过 Binder 调用这些方法 public final void scheduleLaunchActivity(Intent intent, ...) { // 将参数封装成 ActivityClientRecord ActivityClientRecord r = new ActivityClientRecord(); r.intent = intent; // ... // 发送消息给 H,切换到主线程执行 sendMessage(H.LAUNCH_ACTIVITY, r); } public final void schedulePauseActivity(IBinder token, ...) { sendMessage(H.PAUSE_ACTIVITY, token); } public final void scheduleResumeActivity(IBinder token, ...) { sendMessage(H.RESUME_ACTIVITY, token); } public final void scheduleStopActivity(IBinder token, ...) { sendMessage(H.STOP_ACTIVITY_SHOW, token); } public final void scheduleDestroyActivity(IBinder token, ...) { sendMessage(H.DESTROY_ACTIVITY, token); } }

关键体现

  • ApplicationThreadBinder 服务端,运行在 Binder 线程池(非主线程)

  • 当 AMS 要启动/暂停/销毁 Activity 时,跨进程调用ApplicationThread的方法

  • ApplicationThread收到调用后,通过sendMessage()将任务抛回主线程H处理

  • 这是典型的Binder 线程 → 主线程 的线程切换模型


4. 管理应用全局状态

ActivityThread持有一系列应用级别的核心对象:

java

public final class ActivityThread { // 当前应用的 Application 对象 Application mInitialApplication; // 当前应用的所有 Activity 记录 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); // 当前应用的所有 Service 记录 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); // 当前应用的 ResourcesManager final ResourcesManager mResourcesManager; // 当前应用的 LoadedApk(包含 APK 信息、ClassLoader 等) final ArrayMap<String, LoadedApk> mPackages = new ArrayMap<>(); // 主线程 Handler final H mH = new H(); }

关键体现

  • 它管理着整个应用的 Activity、Service、Application 实例

  • 它负责加载 APK 资源(通过LoadedApkResourcesManager

  • 它是单例的(通过sCurrentActivityThread静态变量持有)


5. 创建并绑定 Application

ActivityThread.attach()中:

java

private void attach(boolean system, long startSeq) { // 获取 AMS 的代理 final IActivityManager mgr = ActivityManager.getService(); try { // 将 ApplicationThread 注册到 AMS mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } }

AMS 收到attachApplication后,会反向调用ApplicationThread.bindApplication(),最终触发:

java

// ActivityThread.java private void handleBindApplication(AppBindData data) { // 1. 创建 LoadedApk // 2. 创建 Instrumentation // 3. 创建 Application Application app = data.info.makeApplication(...); // 4. 调用 Application.onCreate() mInstrumentation.callApplicationOnCreate(app); }

关键体现

  • Application.onCreate()不是凭空调用的,是由ActivityThreadhandleBindApplication中触发的

  • 这再次证明ActivityThread是应用组件生命周期的总调度中心


三、总结:为什么说 ActivityThread 是主线程的管理者?

表格

维度具体体现
进程入口ActivityThread.main()是应用进程启动后的第一个 Java 方法,负责初始化主线程 Looper
消息循环主线程的Looper.loop()main()中启动,ActivityThread掌控消息循环的生命周期
任务分发内部类H(Handler)接收所有系统指令(LAUNCH、PAUSE、RESUME、DESTROY),在主线程分发执行
跨进程桥接ApplicationThread(Binder)接收 AMS 指令,通过H切换到主线程,实现Binder 线程 → 主线程的调度
组件管理管理 Application、所有 Activity/Service 实例、Resources、LoadedApk 等全局状态
生命周期触发handleLaunchActivityhandleResumeActivity等方法最终调用Instrumentation,触发你的onCreateonResume

四、一张图看懂关系

plain

┌─────────────────────────────────────────────────────────────┐ │ 系统进程 (system_server) │ │ ActivityManagerService (AMS) │ └──────────────────────┬──────────────────────────────────────┘ │ 跨进程 Binder 调用 ▼ ┌─────────────────────────────────────────────────────────────┐ │ 应用进程 (App Process) │ │ │ │ ┌─────────────────┐ ┌─────────────────────────────┐ │ │ │ ApplicationThread │◄──│ Binder 线程池(非主线程) │ │ │ │ (Binder 服务端) │ └─────────────────────────────┘ │ │ └────────┬────────┘ │ │ │ sendMessage(H.XXX) │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────────────────┐ │ │ │ H │────►│ 主线程 MessageQueue │ │ │ │ (Handler) │ │ (Looper.loop() 循环) │ │ │ └────────┬────────┘ └─────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ handleLaunchActivity() │ │ │ │ handleResumeActivity() │ │ │ │ handlePauseActivity() │ │ │ │ handleDestroyActivity() │ │ │ └────────┬────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────────────────┐ │ │ │ Instrumentation │────►│ Activity.onCreate() │ │ │ │ │ │ Activity.onResume() │ │ │ └─────────────────┘ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ActivityThread (单例) │ │ │ │ • 持有 mH (Handler) │ │ │ │ • 持有 mActivities (Activity 集合) │ │ │ │ • 持有 mInitialApplication │ │ │ │ • 持有 mAppThread (ApplicationThread) │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

五、一句话总结

ActivityThread不是线程本身,但它是主线程的"大脑":它占据了主线程的main()入口,启动了主线程的 Looper 循环,并通过内部 HandlerH统一接收和分发所有系统级指令(Activity 生命周期、Service 启动等),因此它是 Android 应用主线程的实际管理者。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/9 5:44:23

Matlab数字滤波实战:从Butterworth到小波变换

1. 项目概述&#xff1a;用Matlab玩转数字滤波数字信号处理是现代工程领域的基石&#xff0c;而滤波技术则是其中最核心的武器库。作为一名长期混迹在信号处理一线的工程师&#xff0c;我经常需要快速验证各种滤波算法在实际场景中的表现。Matlab凭借其强大的矩阵运算能力和丰富…

作者头像 李华
网站建设 2026/8/9 5:43:06

深度揭秘:天津市城乡建设网站如何成为市民办事与政策查询的核心入口

今天咱们不聊那些高大上却遥不可及的概念,就聊聊一个跟咱们天津百姓生活紧密相连,却又常常被忽略的幕后英雄——天津市城乡建设网站。你可能觉得,这是个政府网站吧?有点严肃,有点枯燥。但我想告诉你,如果你没好好逛过这个网站,或者不知道怎么用这个网站,那你可能正在错…

作者头像 李华
网站建设 2026/8/9 5:41:22

芯片焊接测试实战:BGA虚焊案例的经验复盘

项目背景&#xff1a;高密度封装芯片的焊接测试难题 去年下半年&#xff0c;我们承接了一款车规级通信模组的可靠性验证项目&#xff0c;核心器件是0.8mm间距的BGA封装主控芯片。按照常规流程&#xff0c;首件样品焊接后需要依次完成外观检查、X-Ray无损检测、金相切片分析和电…

作者头像 李华
网站建设 2026/8/9 5:41:17

国内AI短剧出海多语言制作服务商推荐

随着国产短剧出海走向拉美、欧洲市场&#xff0c;多语言制作能力已经成为出海团队的硬性刚需。很多团队本身剧本能力很强&#xff0c;但卡在本地化制作环节&#xff1a;翻译、配音、口型匹配、多版本批量生产难以落地。本篇立足海外合规、多语种产能的痛点&#xff0c;解析Alex…

作者头像 李华
网站建设 2026/8/9 5:40:21

大路灯哪个牌子好用又实惠?2026护眼大路灯精选推荐,一目了然

​​作为一名家里养娃的奶爸&#xff0c;我就是我家的“家具管理员”&#xff0c;负责管理家里扫地机器人、洗衣机、空气炸锅以及各个位置的照明灯具。同时我还是一名挑剔的产品经理和亲子博主&#xff0c;从普通台灯到护眼大路灯&#xff0c;我陆续体验和实测过三十多款。临近…

作者头像 李华
网站建设 2026/8/9 5:38:34

XZ6218,18V,250mA稳压LDO芯片

产品概述这是一款高纹波抑制率、低功耗、低压差&#xff0c;具有过流和短路保护的CMOS降压型电压稳压器。这器件具有很低的静态偏置电流&#xff08;3.0μA Typ.&#xff09;&#xff0c;它们能在输入、输出电压差极小的情况下提供250mA的输出电流&#xff0c;并且仍能保持良好…

作者头像 李华