Android里面的startActivity的流程进阶思考

368 阅读3分钟

在 Android 系统中,startActivity()  的流程是一个典型的跨进程协作过程,涉及应用进程ActivityManagerService(AMS)  以及 Binder 驱动。以下是结合系统源码的详细分析,涵盖从应用层调用到底层 Binder 通信的全链路。


1. 应用进程:发起 startActivity() 请求

调用链路

  1. Activity.startActivity()

    // Activity.java
    public void startActivity(Intent intent) {
        startActivity(intent, null);
    }
    
    public void startActivity(Intent intent, @Nullable Bundle options) {
        // 最终通过 Instrumentation 发起调用
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, 
            intent, -1, options, null);
    }
    
  2. Instrumentation.execStartActivity()

    // Instrumentation.java
    public ActivityResult execStartActivity(...) {
        // 通过 ActivityTaskManager 获取 AMS 的 Binder 代理对象
        int result = ActivityTaskManager.getService().startActivity(...);
        checkStartActivityResult(result, intent);
    }
    
    • 关键对象

      • ActivityTaskManager.getService() 返回 IActivityTaskManager 的 Binder 代理对象(即 AMS 的客户端代理)。

2. Binder 通信:应用进程 → AMS

Binder 调用链路

  1. IActivityTaskManagerProxy.startActivity()

    // IActivityTaskManager.aidl 生成的 Proxy 类
    public int startActivity(...) {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        _data.writeStrongBinder(applicationThread); // 传入 IApplicationThread
        // 序列化参数并发送 Binder 事务
        mRemote.transact(START_ACTIVITY_TRANSACTION, _data, _reply, 0);
        _reply.readException();
        return _reply.readInt();
    }
    
    • 关键参数

      • applicationThreadIApplicationThread 的 Binder 对象,用于 AMS 回调应用进程。
  2. Binder 驱动传递事务

    • 通过 mRemote.transact() 触发 JNI 调用进入 Native 层,最终通过 ioctl(BINDER_WRITE_READ) 将事务数据发送到 Binder 驱动。

    • 驱动处理

      1. 根据 Binder 句柄找到 AMS 所在进程(system_server)。
      2. 将事务数据放入目标进程的待处理队列,唤醒 AMS 的 Binder 线程。

3. AMS 处理启动请求

AMS 核心逻辑

  1. ActivityTaskManagerService.startActivity()

    // ActivityTaskManagerService.java
    public final int startActivity(...) {
        return startActivityAsUser(...);
    }
    
    int startActivityAsUser(...) {
        // 调用 ActivityStarter 处理启动逻辑
        return getActivityStartController().obtainStarter(...).execute();
    }
    
  2. ActivityStarter.execute()

    // ActivityStarter.java
    int execute() {
        // 权限检查、Activity 是否存在校验等
        int res = resolveIntent(...);
        // 创建 ActivityRecord 并加入任务栈
        mLastStartActivityResult = startActivityUnchecked(...);
    }
    
  3. 进程检查与创建

    • 若目标 Activity 所在进程未启动,AMS 通过 Process.start() 创建新进程。

    • 关键源码

      // ActivityManagerService.java
      final ProcessRecord startProcessLocked(...) {
          Process.ProcessStartResult startResult = Process.start(...);
      }
      

4. AMS 回调应用进程

通过 IApplicationThread 调度

  1. ApplicationThread.scheduleLaunchActivity()

    // ActivityThread.java(内部类 ApplicationThread)
    public final void scheduleLaunchActivity(...) {
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }
    
    • 关键对象

      • ApplicationThread 是 IApplicationThread.Stub 的实现类,作为 Binder 实体供 AMS 回调。
  2. Handler 处理消息

    // ActivityThread.H(Handler 子类)
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case LAUNCH_ACTIVITY:
                handleLaunchActivity(r);
                break;
        }
    }
    

5. 应用进程创建 Activity 实例

创建 Activity 并触发生命周期

  1. ActivityThread.handleLaunchActivity()

    // ActivityThread.java
    private void handleLaunchActivity(...) {
        // 创建 Activity 实例
        Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        // 调用 onCreate()
        activity.performCreate(r.savedInstanceState);
        // 触发 onStart() 和 onResume()
        handleResumeActivity(r.token, false, r.isForward, ...);
    }
    
  2. Instrumentation.newActivity()

    // Instrumentation.java
    public Activity newActivity(ClassLoader cl, String className, Intent intent) {
        return cl.loadClass(className).newInstance();
    }
    

6. 底层 Binder 驱动交互

Binder 事务传递细节

  1. 驱动层的 binder_transaction 结构体

    // kernel/drivers/android/binder.c
    struct binder_transaction {
        struct binder_work work;
        struct binder_proc *from;  // 发送方进程
        struct binder_proc *to;    // 接收方进程(如 AMS)
        // 事务数据与目标 Binder 对象
    };
    
    • 关键操作

      • 驱动通过 binder_thread_write() 将事务数据写入目标进程的缓冲区。
      • 目标进程的 Binder 线程通过 binder_thread_read() 读取并处理事务。
  2. 线程唤醒机制

    • 驱动通过 wake_up_interruptible() 唤醒 AMS 的 Binder 线程处理事务队列。

总结:startActivity() 全流程

  1. 应用进程:调用 startActivity() → 通过 Binder 发送请求到 AMS。
  2. AMS:校验权限、创建进程(若需要)、调度 Activity 到任务栈。
  3. Binder 驱动:跨进程传递事务数据。
  4. 应用进程:通过 ApplicationThread 接收回调 → 创建 Activity 实例并触发生命周期。

关键源码路径

  • 应用进程

    • Activity.java → Instrumentation.java → ActivityThread.java
  • AMS 侧

    • ActivityTaskManagerService.java → ActivityStarter.java
  • Binder 驱动

    • kernel/drivers/android/binder.c

性能与调试

  • ANR 触发点:若 AMS 处理超时(默认 10 秒),触发 ANR。
  • 优化方向:减少跨进程调用次数、避免主线程阻塞。

通过源码分析可见,startActivity() 的核心在于 跨进程协作 和 Binder 通信机制,理解这一流程对性能优化和复杂问题排查(如 Activity 启动卡顿)至关重要。