如何穿越进程边界就是一个startActivity请求

整个过程涉及两次Binder IPC调用三次进程的协作。下图清晰地展示了整个过程的核心流程与交互:

第一步:从你的App进程到system_server(第一次Binder IPC)

当你在App中调用 startActivity() 时,旅程开始了

  1. 应用层调用
    // 在你的App进程内
    startActivity(new Intent(this, TargetActivity.class));

    这个调用会进入 Activity 类,最终通过 Instrumentation.execStartActivity()

  2. Binder代理封装
    Instrumentation 会通过 ActivityTaskManager.getService() 获取一个 IActivityTaskManager 对象。这个对象看起来像是一个本地对象,但它实际上是一个 Binder代理(Proxy)
    ○ 你的App进程
    :持有 IActivityTaskManager 的 Proxy 对象
    ○ system_server进程:有一个对应的 IActivityTaskManager 的 Stub 对象(具体实现是 ActivityTaskManagerService

  3. 数据打包与传输
    ○ Proxy 对象会将方法名(startActivity)、你的应用身份(ApplicationThread,后面会讲)、Intent、参数等信息打包成一个 Parcel 对象
    ○ 通过 Binder驱动,这个请求被发送到 system_server 进程

  4. system_server端处理
    ○ Binder驱动 将请求传递给 system_server 进程中的目标Binder对象
    ○ ActivityTaskManagerService(ATMS)(AMS的一部分)的 onTransact 方法被调用,它从 Parcel 中解包数据,并执行真正的 startActivity 逻辑

至此,第一次Binder调用完成。控制权从你的App进程转移到了system_server进程的AMS/ATMS中

第二步:AMS在system_server中的决策与处理

现在,AMS/ATMS掌握了主动权,它会做一系列繁重的工作:

  1. 权限检查:检查你的App是否有权限启动这个Activity
  2. Activity解析:如果Intent是隐式的,会通过 PackageManagerService 解析出具体的目标Activity
  3. 栈管理:决定目标Activity应该放在哪个任务栈(Task)的什么位置
  4. 进程检查:检查目标Activity所属的应用进程是否已经启动
    ○ 如果目标进程已存在:直接进入下一步
    ○ 如果目标进程不存在:AMS会请求 Zygote 进程通过 fork() 创建一个新的应用进程

第三步:从system_server到目标App进程(第二次Binder IPC)

现在AMS需要通知目标App进程去创建并运行对应的Activity。这需要另一个Binder调用,但方向反了过来

  1. Binder桥梁:IApplicationThread
    为了与应用进程通信,AMS需要每个应用进程在启动时都向AMS“注册”一个回调接口。这个接口就是 IApplicationThread
    ○ 目标App进程:有一个 IApplicationThread 的 Stub 对象(具体实现是 ActivityThread 内部的 ApplicationThread 类)
    ○ system_server进程:持有目标进程的 IApplicationThread 的 Proxy 对象
  2. AMS发起调用
    AMS通过它持有的那个 IApplicationThread Proxy 对象,调用其 scheduleLaunchActivity() 方法
  3. 第二次Binder传输
    ○ 同样,方法名和参数(Activity信息、Intent、配置等)被打包成 Parcel
    ○ 通过 Binder驱动,这个请求被发送到 目标App进程

第四步:目标App进程中的Activity创建

  1. 目标进程接收请求
    ○ 目标进程中的 ApplicationThread(Stub)的 scheduleLaunchActivity 方法被调用
    ○ 但请注意:运行在Binder线程池中的,不能直接操作UI就是Binder调用
  2. 线程切换:Handler机制
    ApplicationThread 不会直接创建Activity,而是会向主线程的 Handler(即 H,在 ActivityThread 中)发送一个 LAUNCH_ACTIVITY 消息。这样就把控制权从Binder线程交还给了主线程
  3. 主线程处理
    主线程的 Handler 收到消息后,调用 ActivityThread 的 handleLaunchActivity() 方法。在这里,目标App进程会执行经典的Activity创建流程:
    ○ 创建 Activity 对象(通过反射)
    ○ 调用 Activity.attach() 方法,建立上下文、创建 PhoneWindow
    ○ 调用 onCreate()onStart(),最终调用 onResume(),使Activity进入运行状态

总结与核心角色回顾

步骤发起者接收者核心Binder接口目的
1你的App进程system_serverIActivityTaskManager请求AMS启动一个Activity
2system_server (AMS)目标App进程IApplicationThread指示目标进程创建并运行指定的Activity

关键点

  • 两次Binder:整个过程是两次方向相反的Binder IPC
  • 三个进程:你的App进程 ->system_server-> 目标App进程。system_server是中枢指挥系统
  • 代理与桩:Binder的Proxy-Stub模式是跨进程通信的基石
  • 线程切换:在应用进程内,通过Handler将Binder线程的请求转发到主线程执行UI操作
posted @ 2025-10-28 15:38  gccbuaa  阅读(3)  评论(0)    收藏  举报