Android中Activity销毁底层原理

发布于:2025-08-12 ⋅ 阅读:(13) ⋅ 点赞:(0)

Activity销毁底层原理流程图


核心流程详解

1. 用户进程发起销毁
// Activity.java
public void finish() {
    if (mParent == null) {
        int resultCode;
        Intent resultData;
        synchronized (this) {
            resultCode = mResultCode;
            resultData = mResultData; // 保存setResult数据
        }
        // 通过Binder通知AMS
        ActivityManager.getService().finishActivity(mToken, resultCode, resultData, 0);
    }
}
2. AMS处理阶段

3. 暂停当前Activity
  • 关键代码

    // ActivityStack.java
    void startPausingLocked() {
        mPausingActivity = prev;
        prev.state = PAUSING;
        // 通过Binder回调应用进程
        prev.app.thread.schedulePauseActivity(prev.appToken, false);
        schedulePauseTimeout(prev); // 设置超时检测(10s)
    }
  • 超时处理:若10秒内未收到activityPaused()回调,AMS强制推进流程

4. 启动新Activity
// ActivityStackSupervisor.java
void resumeFocusedStackTopActivityLocked() {
    // 回调结果给新Activity
    next.app.thread.scheduleSendResult(next.appToken, results);
    // 启动新Activity
    next.app.thread.scheduleResumeActivity(next.appToken);
}
5. 销毁原Activity

6. 窗口销毁关键
// WindowManagerGlobal.java
void removeView(View view, boolean immediate) {
    ViewRootImpl root = view.getViewRootImpl();
    root.die(immediate); // 触发View树解绑
    root.dispatchDetachedFromWindow(); // 释放Surface
    SurfaceControl sc = root.getSurfaceControl();
    sc.release(); // 通知SurfaceFlinger回收图形缓冲区
}

常见问题

Q1:finish()后Activity是否立即销毁?

A:不是!销毁分三个阶段:

  1. 同步阶段(主线程阻塞):

    • 立即执行onPause()

    • 通过Binder通知AMS

  2. 异步暂停阶段(约10ms):

    • 等待onPause()完成

    • AMS启动新Activity

  3. 延迟销毁阶段(主线程空闲):

    • 执行onStop()onDestroy()

    • 窗口移除和资源回收在VSync信号后完成

Q2:onDestroy()里能做耗时操作吗?

A:绝对禁止!原因:

  1. onDestroy()执行在主线程,阻塞会导致:

    • 新Activity启动延迟(ANR风险)

    • 窗口移除延迟(视觉卡顿)

  2. 正确做法:

    public void onDestroy() {
        // 快速释放资源
        releaseResources();
        // 耗时操作交给子线程
        new Thread(() -> cleanUpDiskFiles()).start();
    }
Q3:Activity结果如何传递?

A:通过AMS中转:

  1. setResult()保存到ActivityRecord

  2. AMS通过scheduleSendResult()回调新Activity

  3. 数据流:

Q4:窗口如何被移除?

A:四步销毁链:

  1. WindowManager.removeView() 触发View树解绑

  2. ViewRootImpl.die() 提交帧回调事件

  3. Surface.release() 通知SurfaceFlinger回收图形缓冲区

  4. Choreographer 在下一VSync信号完成移除


总结

Q:请说明Activity从finish()到完全销毁的底层过程?

A

Activity销毁是一个跨进程协作的过程,核心流程分三个阶段:

1. 发起阶段(用户进程)
调用finish()后:

  • 保存setResult()数据

  • 通过Binder IPC调用AMS的finishActivity()

2. 调度阶段(AMS)
AMS收到请求后:

  • 标记ActivityRecord为FINISHING状态

  • 启动暂停流程:通过Binder回调schedulePauseActivity()

  • 等待onPause()完成(设置10秒超时)

  • 启动下一Activity并传递结果数据

3. 销毁阶段(延迟执行)
当主线程空闲时:

  • AMS发送scheduleStopActivity()scheduleDestroyActivity()

  • 顺序执行onStop()onDestroy()

  • 关键销毁操作:

    • 移除DecorView:WindowManager.removeView()

    • 释放Surface:通过SurfaceControl.release()通知SurfaceFlinger

    • 资源回收:主线程空闲时触发GC

设计精髓

  • 跨进程协作:通过Binder IPC解耦

  • 异步销毁:避免阻塞UI线程

  • 结果中转:AMS保证数据可靠传递

  • 超时机制:防止进程卡死(PAUSE/DESTROY_TIMEOUT)