目录
  1. 1. 一、Activity 的进程归属:ActivityThread 与主线程
    1. 1.1. 1.1 ActivityThread.main——应用进程的起点
    2. 1.2. 1.2 mH——ActivityThread 的内部 Handler
  2. 2. 二、Activity 生命周期状态机
    1. 2.1. 2.1 生命周期状态定义
    2. 2.2. 2.2 生命周期状态迁移图
    3. 2.3. 2.3 Instrumentation——生命周期调用的中介层
    4. 2.4. 2.4 handleLaunchActivity——Activity 启动的核心
  3. 3. 三、Configuration 变化处理
    1. 3.1. 3.1 两种处理模式
    2. 3.2. 3.2 AMS/ATMS 端的处理
    3. 3.3. 3.3 onSaveInstanceState 与恢复
  4. 4. 四、launchMode 对 Task 管理的影响
    1. 4.1. 4.1 四种 launchMode
    2. 4.2. 4.2 源码中的处理(ActivityStarter)
    3. 4.3. 4.3 Intent Flags 与 launchMode 的交互
  5. 5. 五、ActivityClientRecord 与跨进程回调
    1. 5.1. 5.1 ActivityClientRecord 的数据结构
    2. 5.2. 5.2 ApplicationThread——跨进程 Binder 回调
    3. 5.3. 5.3 ClientTransaction 中的生命周期回调链
  6. 6. 六、核心面试题
  7. 7. 七、Activity 的 Window 创建与管理
    1. 7.1. 7.1 activity.attach() 中的 Window 初始化
    2. 7.2. 7.2 Activity.setContentView 的完整链路
    3. 7.3. 7.3 Activity 与 Fragment 生命周期同步
  8. 8. 八、Activity 的过渡与动画
    1. 8.1. 8.1 Activity Transition(共享元素过渡)
    2. 8.2. 8.2 overridePendingTransition
【吃透源码系列】之Activity

Activity 是 Android 四大组件中最直观、最常接触的组件,也是应用架构的核心载体。每一个界面都对应一个 Activity 实例,其背后涉及 ActivityThread 的消息驱动、Instrumentation 的测试/监控层、AMS/ATMS 的远程调度以及 Window 的创建与管理。本文从源码出发,深入剖析 Activity 的生命周期状态机、Configuration 变化处理、launchMode 对 Task 的影响以及跨进程回调机制。

一、Activity 的进程归属:ActivityThread 与主线程

1.1 ActivityThread.main——应用进程的起点

每个 Android 应用进程本质上是由 Zygote fork 出来的 Java 虚拟机进程。进程的 Java 入口是 ActivityThread.main:

// frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
// 0. 安装进程级别的 Trace(用于 systrace 性能分析)
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

// 1. 创建主线程消息循环
Looper.prepareMainLooper();

// 2. 创建 ActivityThread 实例并 attach 到 AMS
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);

// 3. 设置主线程 Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}

// 4. 启动消息循环(永不退出,直到进程被 kill)
Looper.loop();

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

这里的核心要点:

  • Looper.prepareMainLooper() 在主线程创建了一个 Looper 和 MessageQueue;
  • Looper.loop() 进入死循环,不断消费 MessageQueue 中的消息;
  • 所有 Activity 的生命周期回调(onCreate、onStart、onResume 等)都是通过主线程的 Handler(mH)分发执行的。

为什么 Looper.loop() 是死循环但不会导致 ANR?

ANR 的触发条件是在规定时间内没有响应 Input 事件或特定 Message。Looper.loop() 本身只是一个消息泵——当没有消息时,线程在 Linux pipe/epoll 上阻塞等待(通过 nativePollOnce),不消耗 CPU。ANR 是在消息处理耗时过长时触发的,而非”没有消息”时触发。

1.2 mH——ActivityThread 的内部 Handler

// frameworks/base/core/java/android/app/ActivityThread.java
final H mH = new H();

class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int RESUME_ACTIVITY = 107;
public static final int STOP_ACTIVITY = 116;
public static final int DESTROY_ACTIVITY = 109;
public static final int RELAUNCH_ACTIVITY = 126; // 配置变更重建
public static final int NEW_INTENT = 112;
public static final int CONFIGURATION_CHANGED = 118;
public static final int BIND_APPLICATION = 110;

public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
case RESUME_ACTIVITY:
handleResumeActivity(...); break;
case PAUSE_ACTIVITY:
handlePauseActivity(...); break;
case STOP_ACTIVITY:
handleStopActivity(...); break;
case DESTROY_ACTIVITY:
handleDestroyActivity(...); break;
case NEW_INTENT:
handleNewIntent(...); break;
}
}
}

注意:BIND_APPLICATION 消息的优先级最高(排在第一个处理分支中),它负责初始化 Application 和 ContentProvider。这也是 ContentProvider.onCreate 在 Application.onCreate 之前执行的原因——Provider 在 BIND_APPLICATION 消息处理过程中被初始化。

二、Activity 生命周期状态机

2.1 生命周期状态定义

在 AOSP 中,Activity 的生命周期被定义为一组明确的回调方法,但在 ATMS 内部,使用 ActivityRecord.State 枚举管理状态迁移:

// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
enum State {
INITIALIZING, // 初始状态
STARTED, // 已启动但未 resumed
RESUMED, // 前台运行(可交互)
PAUSING, // 正在暂停中(过渡态)
PAUSED, // 已暂停但可见(如被半透明 Activity 覆盖)
STOPPING, // 正在停止中(过渡态)
STOPPED, // 已停止(不可见)
FINISHING, // 正在结束中
DESTROYING, // 正在销毁中
DESTROYED, // 已销毁
RESTARTING_PROCESS // 进程重启中
}

过渡态(PAUSING、STOPPING、DESTROYING)的存在是为了处理异步的跨进程生命周期回调——system_server 发出 pause/stop/destroy 指令后,需要等待 App 进程的确认才能进入最终状态。如果 App 进程在过渡态卡住(如主线程阻塞),会导致 ANR。

2.2 生命周期状态迁移图

      ┌─────────────┐
│ INITIALIZING│
└──────┬──────┘
│ onCreate()
┌──────▼──────┐
│ STARTED │
└──────┬──────┘
│ onStart()
┌──────▼──────┐
┌─────│ RESUMED │◄────────────┐
│ └──────┬──────┘ │
│ │ onPause() │ onResume()
│ ┌──────▼──────┐ │
│ │ PAUSED │──────────────┘
│ └──────┬──────┘
│ │ onStop()
│ ┌──────▼──────┐
│ │ STOPPED │
│ └──────┬──────┘
│ │ onRestart() onDestroy()
│ ┌──────▼──────┐ ┌──────▼──────┐
└─────│ STARTED │ │ DESTROYED │
└─────────────┘ └─────────────┘

2.3 Instrumentation——生命周期调用的中介层

Instrumentation 是 Activity 生命周期回调的中间层。所有 AMS/ATMS 发起的生命周期调用都经过 Instrumentation:

// frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
// 预创建回调
prePerformCreate(activity);
// 调用 Activity.onCreate
activity.performCreate(icicle);
// 后创建回调
postPerformCreate(activity);
}

Instrumentation 的存在使得 Android 测试框架(如 Espresso、Robolectric)可以拦截和监控所有生命周期回调。例如:

// Espresso 的 ActivityMonitor 通过 Hook ActivityThread 的 mInstrumentation
// 替换为自定义的 MonitoringInstrumentation,在 callActivityOnCreate 前后执行测试逻辑

2.4 handleLaunchActivity——Activity 启动的核心

// frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 1. 通过 PKMS 获取 ActivityInfo
ActivityInfo aInfo = r.activityInfo;

// 2. 创建 ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);

// 3. 通过 ClassLoader 加载 Activity 类
java.lang.ClassLoader cl = appContext.getClassLoader();
Activity activity = mInstrumentation.newActivity(cl,
component.getClassName(), r.intent);

// 4. 创建 Application(如果是第一个 Activity)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

// 5. 调用 activity.attach() 建立与 Window 的关联
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);

// 6. 设置主题
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

// 7. 调用 onStart
if (!r.activity.mFinished) {
activity.performStart("handleLaunchActivity");
r.stopped = false;
}

return activity;
}

三、Configuration 变化处理

3.1 两种处理模式

当设备配置发生变化(如屏幕旋转、语言切换、夜间模式切换等)时,Activity 有两种响应模式:

模式 1:重建 Activity(默认行为)
系统销毁 Activity 再重新创建。完整流程:onPause → onStop → onDestroy → onCreate → onStart → onResume。

模式 2:onConfigurationChanged 回调
当 Activity 在 AndroidManifest 中声明 android:configChanges 时,系统不销毁 Activity,而是直接回调 onConfigurationChanged

3.2 AMS/ATMS 端的处理

// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
// 1. 计算配置差异(orientation、screenSize、locale 等)
int changes = mConfiguration.diff(globalConfig);

// 2. 检查 Activity 是否声明了处理这些变化
if (mActivityInfo.getRealConfigChanged() != 0) {
// 只取 Activity 未声明处理的 change
changes &= ~mActivityInfo.getRealConfigChanged();
}

if (changes == 0) {
return true; // Activity 自行处理(onConfigurationChanged)
}

// 3. 有未声明处理的 change → 需要重建
relaunchActivity(..., preservedState);
return false;
}

配置变更类型定义在 android.content.res.Configurationandroid.content.pm.ActivityInfo 中:

  • CONFIG_ORIENTATION = 0x0002
  • CONFIG_SCREEN_SIZE = 0x0400
  • CONFIG_LOCALE = 0x0004
  • CONFIG_KEYBOARD = 0x0010
  • CONFIG_UI_MODE = 0x0200(夜间模式)
  • CONFIG_SCREEN_LAYOUT = 0x0100
  • CONFIG_FONT_SCALE = 0x40000000

3.3 onSaveInstanceState 与恢复

在 Activity 因配置变化被销毁前,系统调用 onSaveInstanceState(Bundle outState) 保存状态:

// frameworks/base/core/java/android/app/Activity.java
final void performSaveInstanceState(@NonNull Bundle outState) {
onSaveInstanceState(outState); // 用户实现的保存逻辑
// 保存 Fragment 状态
mFragments.saveAllState();
// 保存视图层次状态(View 的 onSaveInstanceState)
if (mAutoFillResetNeeded) {
getWindow().saveHierarchyState();
}
}

saveHierarchyState 内部遍历 View 树,为每个 View 调用 dispatchSaveInstanceState() 保存状态(如 EditText 的当前文本和光标位置)。

四、launchMode 对 Task 管理的影响

4.1 四种 launchMode

launchMode 在 AndroidManifest 的 <activity> 标签中声明,或在 Intent 中通过 flags 覆盖。

standard(默认):每次启动都创建新实例,放入调用者所在的 Task。

singleTop:如果目标 Activity 已在栈顶,则复用,调用 onNewIntent();否则新建实例。

singleTask:系统中只能有一个实例。如果已存在但在不同 Task,则将该 Task 移到前台,并清除其上的所有 Activity(或调用 onNewIntent,取决于 FLAG_ACTIVITY_CLEAR_TOP)。

singleInstance:与 singleTask 类似,但该 Activity 独占一个 Task,此 Task 不允许其他 Activity 进入。

4.2 源码中的处理(ActivityStarter)

// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int setTaskFromReuseOrCreateNewTask(Task taskToAffiliate) {
mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);

if (mReuseTask == null) {
// 创建新 Task
final Task task = mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent,
mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind,
mStartActivity, mSourceRecord, mOptions);
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask");
} else {
// 复用已有 Task(singleTask/singleInstance)
addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
}
return START_SUCCESS;
}

4.3 Intent Flags 与 launchMode 的交互

Intent flags 可以覆盖 launchMode 行为:

  • FLAG_ACTIVITY_NEW_TASK:效果等同于 singleTask
  • FLAG_ACTIVITY_CLEAR_TOP:清除目标 Activity 之上的所有 Activity
  • FLAG_ACTIVITY_SINGLE_TOP:效果等同于 singleTop
  • FLAG_ACTIVITY_CLEAR_TASK:启动前清除整个 Task(常与 FLAG_ACTIVITY_NEW_TASK 组合)

当 Intent flag 与 Manifest launchMode 冲突时,ActivityStarter 优先使用 Intent flag。

五、ActivityClientRecord 与跨进程回调

5.1 ActivityClientRecord 的数据结构

App 进程中的每个 Activity 都对应一个 ActivityClientRecord,它包含 Activity 实例及其必要的上下文信息:

// frameworks/base/core/java/android/app/ActivityThread.java
static final class ActivityClientRecord {
IBinder token; // WMS 端的窗口令牌
int ident; // Activity 的唯一标识
Intent intent;
String referrer;
IVoiceInteractor voiceInteractor;
Bundle state; // saved instance state
PersistableBundle persistentState;
Activity activity; // Activity 实例引用
Window window;
Activity parent;
String embeddedID;
Activity.NonConfigurationInstances lastNonConfigurationInstances;
boolean paused;
boolean stopped;
boolean hideForNow;
Configuration newConfig;
Configuration createdConfig;
Configuration overrideConfig;
// ...
}

5.2 ApplicationThread——跨进程 Binder 回调

ApplicationThread 是 ActivityThread 的内部类,继承自 IApplicationThread.Stub,是 system_server 向 App 进程发送生命周期指令的 Binder 接口。

Android 10 引入 ClientTransactionClientLifecycleManager 统一了生命周期事务的编排:

// frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) {
final IApplicationThread client = transaction.getClient();
transaction.schedule(); // 最终调用 ApplicationThread.scheduleTransaction
}

// frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
public void schedule() {
mClient.scheduleTransaction(this); // 跨进程 Binder 调用
}

5.3 ClientTransaction 中的生命周期回调链

一个 ClientTransaction 包含多个 ClientTransactionItem(生命周期回调项),例如:

// 启动 Activity 的典型 transaction
ClientTransaction transaction = ClientTransaction.obtain(app.thread, r.token);
transaction.addCallback(LaunchActivityItem.obtain(/* ... Activity 创建参数 ... */));
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(/* isForward, procState, ... */));
mLifecycleManager.scheduleTransaction(transaction);

LifecycleStateRequest 的含义:它声明了事务执行完成后 Activity 应达到的最终状态。例如,ResumeActivityItem 表示 Activity 最终应为 RESUMED。App 进程收到后,执行所有 callbacks(创建 Activity、onCreate、onStart),最后通过 executeLifecycleState 将 Activity 过渡到目标状态(onResume)。

六、核心面试题

Q1:Activity 的 onNewIntent 在什么场景下被调用?其调用时机是怎样的?

onNewIntent 在 Activity 处于 singleTop(栈顶复用)、singleTask 或 singleInstance 模式时被调用。调用时机通常是:onPause → onNewIntent → onResume(如果 Activity 已经在前台)。如果是后台 Activity 被新 Intent 唤起,则生命周期顺序是:onNewIntent → onRestart → onStart → onResume。在 onNewIntent 中应调用 setIntent(intent) 更新内部存储的 Intent。

Q2:当一个 Activity 被部分遮挡(比如弹出 Dialog),它的生命周期如何变化?为什么?

弹出 Dialog 是同一个应用进程内的操作,不触发 AMS 级别的生命周期回调。Dialog 本质上是 Activity Window 之上的一个子窗口(type = TYPE_APPLICATION),Activity 仍然处于 RESUMED 状态。但如果启动一个半透明的 Activity 覆盖在上面,下层 Activity 执行 onPause()(停止交互但可见),进入 PAUSED 状态。Android 10+ 半透明 Activity 不再允许 resumedOnTop。

Q3:Activity 的重建机制中,onRetainNonConfigurationInstance 和 ViewModel 的关系是什么?

onRetainNonConfigurationInstance() 是 Android 早期提供的跨配置变更保留对象机制。在 Android Architecture Components 推出后,ViewModel 成为推荐的方式,内部正是基于此机制实现的——ComponentActivity 的 getLastNonConfigurationInstance() 保存着 ViewModelStore,在 Activity 重建时恢复 ViewModel 实例。

Q4:ActivityThread 的 main 方法中为什么需要 Looper.loop() 死循环?

Android 应用的主线程是一个事件驱动模型。所有 UI 操作、生命周期回调、触摸事件分发都需要在主线程中串行处理。Looper.loop() 提供了这个串行化的事件处理循环。如果退出循环,主线程就没有办法再接收和处理任何消息——所有 UI 操作都会失败,进程实际已处于”假死”状态。

Q5:为何 onStart 和 onResume 之间需要区分?两者状态的区别是什么?

onStart 标志 Activity 变为可见(Activity 进入 STARTED 状态),onResume 标志 Activity 变为前台可交互(进入 RESUMED 状态)。区别场景:当启动一个半透明 Activity 时,下层 Activity 调用 onPause(进入 PAUSED,停止交互但可见),当半透明 Activity 关闭时,下层 Activity 调用 onResume 恢复交互——但不会再次调用 onStart/onStop(因为始终可见)。

七、Activity 的 Window 创建与管理

7.1 activity.attach() 中的 Window 初始化

performLaunchActivity 中调用 activity.attach(),这是 Activity 与其 Window 建立关系的时刻:

// frameworks/base/core/java/android/app/Activity.java
final void attach(Context context, ActivityThread aThread, ...) {
// 1. 创建 PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);

// 2. 设置 Callback——将 Activity 自身注册为 Window 的事件接收者
mWindow.setCallback(this); // 触摸事件、菜单事件流回 Activity

// 3. 设置 WindowManager
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

mWindowManager = mWindow.getWindowManager();
}

7.2 Activity.setContentView 的完整链路

// Activity.java
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID); // 委托给 PhoneWindow
initWindowDecorActionBar(); // 初始化 ActionBar
}

// PhoneWindow.java
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor(); // 创建 DecorView 并 inflate 系统布局模板
}
// inflate 用户布局到 R.id.content 中
mLayoutInflater.inflate(layoutResID, mContentParent);
}

7.3 Activity 与 Fragment 生命周期同步

Fragment 的生命周期由 FragmentManager 管理,但与 Activity 生命周期紧密耦合:

Activity.onCreate → FragmentManager.dispatchCreate()
Activity.onStart → FragmentManager.dispatchStart()
Activity.onResume → FragmentManager.dispatchResume()
Activity.onPause → FragmentManager.dispatchPause()
Activity.onStop → FragmentManager.dispatchStop()
Activity.onDestroy → FragmentManager.dispatchDestroy()

对于 Fragment 的视图生命周期(onCreateView → onDestroyView),FragmentManager 在 Fragment 切换时独立管理,与 Activity 的生命周期不完全一致。例如:Fragment A 替换为 Fragment B 时,A 调用 onDestroyView(视图销毁),但 A 的 onDestroy 只在 Activity destroy 时才调用。

八、Activity 的过渡与动画

8.1 Activity Transition(共享元素过渡)

Android 5.0 引入了 Activity Transition API,支持共享元素动画:

// 启动 Activity 时指定共享元素
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation(activity,
Pair.create(logoView, "logo_transition"),
Pair.create(titleView, "title_transition"));
ActivityCompat.startActivity(activity, intent, options.toBundle());

AMS 端处理:在 ActivityStarter 中,检查传入的 Bundle 中是否有 android:transitionName 映射。如果有,在 start 和 finish 时播放过渡动画。

8.2 overridePendingTransition

// 自定义 Activity 切换动画
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);

这个方法必须在 startActivity()finish() 之后立即调用。它在 Android 内部通过 ActivityRecord 的动画状态控制。

AOSP 核心路径参考:

  • frameworks/base/core/java/android/app/ActivityThread.java
  • frameworks/base/core/java/android/app/Activity.java
  • frameworks/base/core/java/android/app/Instrumentation.java
  • frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
  • frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
打赏
  • 微信
  • 支付宝

评论