理解Android中的进程通信

众所周知 Android 中采用 Binder 机制来进行进程通信,且应用层基于 Binder 封装了几种特定类型的通信方式来简化不同场景下的进程通信,正确理解 Binder 对于理解整个 Android 系统有着至关重要的作用,Binder 底层原理十分复杂且难以理解,如果直接去看源码容易身陷其中不知所云,网上已经有一批学习 Binder 的深度好文,我们可以先在熟练使用 AIDL 或者手写 Binder 进行进程通信的前提下来阅读这些文章并亲自跟踪源码来逐步“掌控”它,本文的内容对于具体实现原理方面不会过多涉及,主要从上层需求及设计层面来自顶向下分析,大概分三个部分,第一部分为 Binder 的介绍,第二部分为 Android 中的几种特定 Binder,第三部分从 Activity 的启动流程来分析 Binder 在其中的作用。

背景知识

进程隔离

进程隔离的存在使得进程之间互相交流时需要进行进程通信,简单来说进程隔离是为了保证进程间互不影响,试想如果不隔离,用户创建的一个进程挂掉了可能会导致其它的进程也会随之挂掉,显然这样不合理,进程隔离的维基百科解释如下:

进程隔离是为保护操作系统中进程互不干扰而设计的一组不同硬件和软件的技术。这个技术是为了避免进程A写入进程B的情况发生。 进程的隔离实现,使用了虚拟地址空间。进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B。

进程通信

不同进程间使用的内存空间不同,相互之间不能直接进行访问通信,如果进程间需要进行通信,必定需要借助一个公共的第三方内存空间来完成,这个第三方空间有两种形式,第一种就是共享内存,即不同进程间共享有着一份相同的内存区间,第二种就是使用内核空间来中转,内核充当中间人的角色 ,用来连接不同进程间的数据交互,内核是系统的核心,安全级别很高,不是随随便便能访问的,不然弄坏了咋办,内核空间向外界暴露一些接口供其调用(系统调用),通过统一的接口,所有的资源访问都是在内核的控制下执行,以免导致用户程序对系统资源的越权访问,从而保证了系统的安全和稳定。

当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)此时处理器处于特权级最高的(0级)内核代码中执行。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。处理器在特权等级高的时候才能执行那些特权CPU指令

为什么是 Binder ?

Android系统是基于 Linux 系统的,在 Linux 系统上进程通信已经有了一些解决方案 如管道,消息队列, 共享内存, Socket等, 管道,消息队列,Socket都是内核作为中转的通信实现方式,共享内存则是以消除内存隔离直接访问的形式来进行通信。
那么既有方案这么多,为什么要重新造出一个 binder 来进行进程通信呢?主要是基于两点考虑,效率安全性

  • 效率
    管道,消息队列,Socket 用内核作为中转的方式会经历2次内存拷贝,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区。共享内存虽然无需拷贝,但控制复杂,难以使用。而 Binder 采用内存映射的方式只需要一次拷贝,所以在效率上大大提升。


    传统通信

    Binder通信
  • 安全性
    Android 作为一个开放式的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。传统 IPC 没有任何安全措施,完全依赖上层协议来确保,容易被伪造。而Binder机制从协议上支持通信双方的身份验证,不易被篡改,所以在安全性上大大提升。

Binder

Binder 采用C/S架构的通信方式,类似于传统的 web 通信,请求发起方为 Client 端,请求接收处理方为 Server 端,具有同传统 C/S 架构相同的模块,如通信入口、通信协议、Server 端接收线程管理等等,同时又具有面向对象的特性,这里引用一段Android Bander设计与实现 - 设计篇的描述再合适不过:

面向对象思想的引入将进程间通信转化为通过对某个 Binder 对象的引用调用该对象的方法,而其独特之处在于 Binder 对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。最诱人的是,这个引用和java里引用一样既可以是强类型,也可以是弱类型,而且可以从一个进程传给其它进程,让大家都能访问同一 Server ,就象将一个对象或引用赋值给另一个引用一样。Binder 模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。形形色色的Binder对象以及星罗棋布的引用仿佛粘接各个应用程序的胶水,这也是Binder在英文里的原意

这种 C/S 通信方式在 Binder 的实现中有四种角色:Server,Client,ServiceManager 以及 Binder 驱动,类似于 Web 通信中的 Web 服务器,App或者浏览器,DNS域名服务器,路由器。

大概流程如上图所示:服务端先将提供的服务注册到 ServiceManager, 客户端调用时根据事先注册的标识符字符串来从中间者 ServiceManager 中查找相关服务,并通过 Binder 驱动完成对相应服务的通信过程,这里的标识符字符串类似于 Web 通信中的 url。
不同于 web 通信通过 url 只拥有执行具体单个方法的能力的是 Binder 机制中通过标识符字符串客户端会持有目标服务接口对象,拥有访问其所有公有方法和字段的能力,不过该对象并不是真实对象而是一个代理对象,它会将输入数据和具体方法的 KeyCode 包装起来交给 Binder 驱动,Binder 驱动完成底层数据传输到服务器中的具体实现 Binder 真实对象,解析数据并完成真实的操作并将数据返回。

说了这么多理论,我们再来看一下一个简单的 Binder 使用的代码实现加深下理解。

1 定义一个有数字相加能力的接口,此处需要继承IInterface接口

public interface ICalculateManager extends IInterface {
    int add(int a, int b) throws RemoteException;
}

2 添加服务端的这个接口的具体实现,需要继承 Binder 使其拥有跨进程通信的能力

class Stub extends Binder implements ICalculateManager {
        public static final String DESCRIPTOR = "com.ethanhua.artstudydemo.ipc.ICalculateManager";

        public Stub() {
            attachInterface(this, DESCRIPTOR);
        }

        public static ICalculateManager asInterface(IBinder obj) {
            if (obj == null) {
                return null;
            }
            IInterface localI = obj.queryLocalInterface(DESCRIPTOR);
            if (localI != null && localI instanceof ICalculateManager) {
                return (ICalculateManager) localI;
            }
            return new Proxy(obj);
        }

        @Override
        public IBinder asBinder() {
            return this;
        }

        @Override
        protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
            switch (code) {
                case TRANSACTION_add: {
                    data.enforceInterface(DESCRIPTOR);
                    int[] intArr = data.createIntArray();
                    int value = add(intArr[0], intArr[1]);
                    reply.writeNoException();
                    reply.writeInt(value);
                    return true;
                }
                default:
                    break;
            }
            return super.onTransact(code, data, reply, flags);
        }

        @Override
        public int add(int a, int b) throws RemoteException {
            return 2 * (a + b);
        }
    }

asInterface 方法中会判断是否是本地 Binder 对象还是远程 Binder 对象,如果是本地 Binder 对象直接转换成对应的功能接口对象返回,如果是远程代理对象,则构建一个代理类返回,外界通过这个代理类来完成功能调用。

onTransact 方法完成实际的数据解析及方法调用,可以看出 Binder 通信中采用 Parcel 这种数据结构存储输入函数的参数值和函数执行的返回值,也就是为什么四大组件中采用 Parcelable 作为通信数据结构。code 用来标识具体请求调用哪一个方法。

3 添加代理类实现

public  class Proxy implements ICalculateManager {
            private IBinder mRemote;

            public Proxy(IBinder remote) {
                this.mRemote = remote;
            }

            @Override
            public int add(int a, int b) throws RemoteException {
                Parcel data = Parcel.obtain();
                Parcel reply = Parcel.obtain();
                int result;
                data.writeIntArray(new int[]{a, b});
                mRemote.transact(TRANSACTION_add, data, reply, 0);
                reply.readException();
                result = reply.readInt();
                reply.recycle();
                data.recycle();
                return result;
            }

            @Override
            public IBinder asBinder() {
                return mRemote;
            }
}

add 方法内中会将参数打包调用远程代理对象的 transact方法去执行对应的方法,transact 最终会调用到上面 stub 类中的 onTransact 方法

4 注册到 ServiceManager

ServiceManager.addService(ICalculateManager.Stub.DESCRIPTOR, ICalculateManager.Stub())

5 发起调用

val iBinder = ServiceManager.getService(ICalculateManager.Stub.DESCRIPTOR) //获取注册的IBinder
val calManager = ICalculateManager.Stub.asInterface(iBinder) //转换为数字相加功能接口对象
Log.e("event", "ipc sum:${calManager.add(0, 1)}") // 调用其add方法得到计算结果

整个流程是: 首先通过 ServiceManager 注册 ICalculateManager.Stub 的远程代理对象,因为 ServiceManager 也是运行在一个独立进程中,所以这个过程也是一个跨进程通信,那怎样才能拿到 ServiceManager 呢?Binder 中通过提前预置 ServiceManager 来解决这个问题,每个客户端通过写死的0号引用来获取 ServiceManager,类似于域名服务器地址,你得提前预置好。然后客户端通过 ServiceManager 来获取已经注册好的远程代理对象,调用这个对象的本地代理对象对应的方法传输该方法的参数、标识符到远程进程,远程进程通过创建好的线程来接收此次调用,并执行对应的 onTransact 方法解析数据完成实际的方法调用,并将结果返回。

Android中几种特定的 Binder

虽然 Binder 为进程通信提供了支持,但是一些通用的场景还是需要进行一些封装来简化调用,下面我们来看一下 Android 上基于 Binder 的一些上层封装。

ActivityManagerService

ActivityManagerService 虽名为 Activity 管理服务但它不仅仅管理 Activity, Android 中四大组件之间的通信都是依赖于它来进行,ActivityManagerService 继承自 ActivityManagerNative,而 ActivityManagerNative 是一个实现了 IActivityManager 功能的 Binder,ActivityManagerService 这里类似于上面的 ICalculateManager.Stub() 是服务端的 Binder 功能实现类。它的客户端代理类是 ActivityManagerProxy,它的注册是在系统启动过程中被注册的,具体是在 SystemServer 中的 startBootstrapServices() 方法中调用 ActivityManagerService.setSystemProcess() 方法中向 ServiceManager 中注册的,它的代理对象保存在 ActivityManagerNative 的单例 gDefault 字段中。

**[ActivityManagerService.java]**
public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); //注册 ActivityManagerService
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));

            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

            synchronized (this) {
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (mPidsSelfLocked) {
                    mPidsSelfLocked.put(app.pid, app);
                }
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }
        } catch (PackageManager.NameNotFoundException e) {
           ...
        }
    }
**[ActivityManagerNative.java]**
public abstract class ActivityManagerNative extends Binder implements IActivityManager {
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            return ActivityManagerNative.asInterface(ServiceManager.getService("activity"));
        }
    };
    ...
}

AIDL

AIDL ( Android Interface Definition Language ) Android 接口定义语言

通过查看 AIDL 生成的 Java 代码可以看出 AIDL 只是 Google 为了简化开发者编写 Binder 进程通信代码搞出来的一套东西,其实可以看出前面的 Binder 示例代码中有很大一部分是模板代码,变化的只是功能接口的定义和实现,所以现在只需要定义一个功能接口的 AIDL 文件,编译器会自动帮我们生成代理类 Proxy 和原始类 Stub,我们只需要再实现原始类 Stub 中定义好的接口功能方法就行了。
之后一般我们会借助 Service 类来完成整个跨进程通信,这其实是一种匿名 Binder 通信过程,因为我们并没有注册该服务,而是借助 Service 实名 Binder(ActivityManangerService) 来承载的,API 26 以后系统隐藏了 ServiceManager,我们不能直接拿到 ServiceManager 来完成注册和获取了,这时我们就可以通过这种已经注册好的实名 Binder 来承载我们自定义的匿名 Binder 完成通信。

ContentProvider

ContentProvider 内容提供者,顾名思义这是一个数据提供功能的封装,在 Android 平台上不同应用间或者同一个应用中经常会有数据共享的需求,这就需要进程通信了,进程通信可以用 Binder 搞定,我们可以按照通用步骤:定义接口,注册服务,然后向外界暴露服务标识符,通过标识符来获取服务来实现或者简单点用 AIDL 来搞定,为什么要搞出一个 ContentProvider 呢?在我看来主要有两点:

  • 统一规范
    ContentProvider 中定义了数据增,删,改,查操作的抽象方法,我们可以通过继承 ContentProvider 来完成具体的实现,试想如果没有这一套标准,通过AIDL 不同应用定义的数据共享操作接口方法各不相同,调用方还需要拷贝其接口文件完成转换调用,每需要访问另外一个应用或者进程的数据就需要拷贝一份 AIDL文件,这里就耦合了服务端的接口定义,有了 ContentProvider 了之后所有调用方不需要知道服务端的具体接口定义(因为统一了标准),直接使用其增,删,改,查方法即可,如果操作的数据结构相同,调用方调用不同服务端时还可以复用同一份调用代码。

  • 抽象封装,简化代码
    AIDL 是一种功能无关的进程通信方式,数据共享操作只是其中的一种特定功能的操作,所以我们抽象出了里面的增,删,改,查四种操作,单一其职责,使其只负责共享数据的这四种操作,其它操作不提供,那客户端怎么找到我们在服务端基于此接口的具体实现呢?这里通过 Uri 来定位,客户端只需要调用 ContentResolver 传入 uri 来进行调用,简单高效,如调用系统通讯录:

    val cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,
                  arrayOf(ContactsContract.Contacts._ID,
                          ContactsContract.Contacts.DISPLAY_NAME),
                  null, null, null)
          while (cursor.moveToNext()) {
              val long = cursor.getLong(0)
              val name = cursor.getString(1)
              Log.e("event", "$long-$name")
          }
    

实现层面 ContentProvider 同样是借助 ActivityManagerService 来完成跨进程通信的,由于采用是匿名Binder(为什么会采用这种匿名方式而不是直接采用注册到 Service,省去与系统 ContentProvider 容器通信的这一步的原因我也不太明白,难道是为了保证 ServiceManager 里面 Service 的纯正和大小?), 需要一个系统级别的类似于 ServiceManager 的东西来管理所有注册的 ContentProvider,所以就有了 ContentResolver,首先通过与系统进程通信拿到匹配的ContentProvider,然后与 ContentProvider 所在进程进行通信执行对应的增、删、改、查方法,具体的代码调用流程感兴趣的可以跟踪下源码,这里就不再说了。

一次Query流程图

BroadcastReceiver

广播是一种一对多的进程通信方式,一个调用方调用多个被调用方,而文章前面涉及到的都是多个客户端(调用方)调用同一个服务端(被调用方)的多对一的通信方式,要做到这种一对多的通信方式必须在上层进行封装,也就是我们常见的观察者模式,服务端首先注册接收器到系统的某个容器中(BroadcastRecord,里面包含一个有序接收器队列和一个并行接收器队列),客户端发送请求时通过与系统的进程通信在这个系统容器中查找其所有适配的接收器,然后再通过进程通信执行所匹配到的所有接收器所在进程对应的观察方法,其中的第一次进程通信是依赖 ActivityManagerService 的进程通信,第二次是 IIntentReceiver 匿名 Binder 进程通信,大概流程如下图,感兴趣的可以自行跟踪源码。

Messenger

Messenger 顾名思义是一种基于消息的通信方式,特点是通信双方可以相互发消息进行通信,而 Binder 通信是单向的,谁发起请求谁就是客户端,谁接收请求谁就是服务端,要想实现双向通信必须接收方可以持有对方的引用再反向通信调用方,一个简单的方法就是使用 Binder 承载匿名 Binder 的方式:在第一次进程通信的时候,传输一个 Binder 给服务端,服务端再拿到这个客户端的代理 Binder,再反向通信从而完成双向通信,Messenger 就是简化这一套操作抽象出来的东西,IMessenger.Stub 就是有消息发送能力的接口 Binder,由于 Messenger 发送消息采用了 handler 中向应用主线程消息队列中 sendMessage 的实现方式,所以这个远程进程通信过程是异步的(通信后立即返回,不必等到这个消息的处理逻辑过程的完成),串行的(多个客服端向服务端发消息时,都会发送到服务端的消息队列中等待主线程顺序执行),同样第一次通信过程一般采用 Service 来进行进程通信,在 Service 中返回 Messenger 对象,而这个 Messenger 对象发送消息 Message 时又可以携带一个回执 Messenger(Message.replyTo),这样就可以实现双方一直双向通信了。

Activity 启动流程

Activity 是一个用来和用户交互的 UI 抽象类,其中封装了视图、交互事件,由于视图、事件都是系统底层的资源所以需要与系统进行进程通信,同时 Activity 与四大组件间也需要通信,Activity 是我们开发中经常用到的类,所以理解它十分重要。
首先我们来看一下通信双方的 Binder 接口定义:Activity 调用系统进程中的 ActivityService 服务的 Binder 接口为 ActivityServiceNative,系统进程完成一些资源的创建后需要回调应用进程,这个过程的通信 Binder 接口为 ApplicationThreadNative ,虽然这两个接口的定义的方法很多,但大体上就是四大组件的启动方法和对应的生命周期方法。下面我们来具体跟踪下 Activity 的启动过程源码。

用户 App 进程

Activity中调用 startActivity 经过一些重载方法后最终会调用到 startActivityForResult

**[Activity.java]**
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }
            cancelInputsAndStartExitTransition(options);
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

这里的两个分支最终都会调用 mInstrumentation.execStartActivity(),这个 mInstrumentation 对象非常重要,后面很多操作都需要它来完成,关于它是什么,在何时何地被创建,有什么作用,后来会介绍,我们继续来跟踪

**[Instrumentation.java]**
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault() //获取AMN代理Binder进行进程通信
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

这里会调用 ActivityManagerNative.getDefault().startActivity(),返回值为一个 int 值类型结果码用来确定结果,checkStartActivityResult 方法中会根据返回的结果码匹配抛出对应的异常,这里就有我们常见的 “ 找到不对应的Activity错误 ”,ActivityManagerNative.getDefault() 是一个 ActivityManagerService 本地代理单例

**[ActivityManagerNative.java]**
public abstract class ActivityManagerNative extends Binder implements IActivityManager {
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            return ActivityManagerNative.asInterface(ServiceManager.getService("activity"));
        }
    };
}

从这里开始就要进行进程通信了

**[ActivityManagerProxy.java]**
public int startActivity(IApplicationThread var1, String var2, Intent var3, String var4, IBinder var5, String var6, int var7, int var8, ProfilerInfo var9, Bundle var10) throws RemoteException {
        Parcel var11 = Parcel.obtain();
        Parcel var12 = Parcel.obtain();
        // 打包输入参数数据
        var11.writeInterfaceToken("android.app.IActivityManager");
        IBinder var13;
        if (var1 != null) {
            var13 = var1.asBinder();
        } else {
            var13 = null;
        }
        var11.writeStrongBinder(var13);
        var11.writeString(var2);
        var3.writeToParcel(var11, 0);
        var11.writeString(var4);
        var11.writeStrongBinder(var5);
        var11.writeString(var6);
        var11.writeInt(var7);
        var11.writeInt(var8);
        if (var9 != null) {
            var11.writeInt(1);
            var9.writeToParcel(var11, 1);
        } else {
            var11.writeInt(0);
        }

        if (var10 != null) {
            var11.writeInt(1);
            var10.writeToParcel(var11, 0);
        } else {
            var11.writeInt(0);
        }
        // Binder 进程通信 
        this.mRemote.transact(3, var11, var12, 0); 
        //解析返回数据
        var12.readException();
        var7 = var12.readInt();
        var12.recycle();
        var11.recycle();
        return var7;
    }

依然是对一些参数的包装,并调用this.mRemote.transact(3, var11, var12, 0) 进行进程通信,最终会调用到 ActivityManagerNative.onTransact() 方法进入 ActivityManagerService 服务进程

ActivityManagerService 服务进程

从这里就进入到 ActivityManagerService 服务进程的部分了,我们继续追踪:

**[ActivityManagerService.java]**
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b); // 获取与 App 用户进程通信的 Binder
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
        ...
        ...
}

根据 code 为 3 匹配到 START_ACTIVITY_TRANSACTION 分支,进行一些数据解析,其中 IApplicationThread app = ApplicationThreadNative.asInterface(b) 取得与应用进程通信的 Binder 对象,为后面的与用户 App 进程通信做支持,然后调用 startActivity 方法,辗转后调用 ActivityStarter.startActivityMayWait() 方法

**[ActivityStarter.java]**
final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration config, Bundle options, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask) {
    ...
    //创建新的Intent对象,即便intent被修改也不受影响
    intent = new Intent(intent);

    //收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity
    ResolveInfoActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

    ActivityStackSupervisor.ActivityContainer container = (ActivityStackSupervisor.ActivityContainer)iContainer;
    synchronized (mService) {
        ... //something not important
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);

        Binder.restoreCallingIdentity(origId);
        ...
        return res;
    }
}

会通过 resolveActivity 来获取 ActivityInfo 信息 , 换句话来说就是会检查系统中所有安装了的 App 中是否有该 Intent 的目标 Activity 被注册( Manifests 文件中注册)然后再进入 ActivityStarter.startActivityLocked(),接下来的调用链分支比较多,大多逻辑是根据 Activity 的四种启动模式来执行不同的逻辑块,我们选取正常的分支: 启动模式为 Normal,启动的 Activity 与现在 Activity 不同且在同一个栈中的情况来跟踪,调用链为:
-> ActivityStarter.startActivityUnchecked()
-> ActivityStarter.resumeTargetStackIfNeeded()
-> ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
-> ActivityStack.resumeTopActivityUncheckedLocked()
-> ActivityStack.resumeTopActivityInnerLocked()

**[ActivityStack.java]**
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ... //系统没有进入booting或booted状态,则不允许启动Activity

        //需要等待暂停当前activity完成,再resume top activity
        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
        //暂停其他Activity
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            //当前resumd状态activity不为空,则需要先暂停该Activity
            pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
        }
        if (pausing) {
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
                    "resumeTopActivityLocked: Skip resume: need to start pausing");
            //更新目标Activity进程 LruCache
            if (next.app != null && next.app.thread != null) {
                mService.updateLruProcessLocked(next.app, true, null);
            }
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()) {
            // 如果下一个Activity不需要等待暂停完成,那么当我们暂停上面的堆栈时,就可以恢复Activity。所以,除了确保我们已经执行了任何挂起的 Transition,因为在这一点上应该没有任何事情要做。
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }

        // If the most recent activity was noHistory but was only stopped rather
        // than stopped+finished because the device went to sleep, we need to make
        // sure to finish it as we're making a new activity topmost.
        if (mService.isSleepingLocked() && mLastNoHistoryActivity != null &&
                !mLastNoHistoryActivity.finishing) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                    null, "resume-no-history", false);
            mLastNoHistoryActivity = null;
        }

        if (prev != null && prev != next) {
            if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                    && next != null && !next.nowVisible) {
                mStackSupervisor.mWaitingVisibleActivities.add(prev);
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                        "Resuming top, waiting visible to hide: " + prev);
            } else {
                //隐藏上一个Activity的窗口
                if (prev.finishing) {
                    mWindowManager.setAppVisibility(prev.appToken, false);
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                            "Not waiting for visible to hide: " + prev + ", waitingVisible="
                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                            + ", nowVisible=" + next.nowVisible);
                } else {
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                            "Previous already visible but still waiting to hide: " + prev
                            + ", waitingVisible="
                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                            + ", nowVisible=" + next.nowVisible);
                }
            }
        }

        ... // 通过 WindowManager 隐藏上一个 Activity
        boolean anim = true;
        if (prev != null) {
            if (prev.finishing) {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare close transition: prev=" + prev);
                if (mNoAnimActivities.contains(prev)) {
                    anim = false;
                    mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    mWindowManager.prepareAppTransition(prev.task == next.task
                            ? TRANSIT_ACTIVITY_CLOSE
                            : TRANSIT_TASK_CLOSE, false);
                }
                mWindowManager.setAppVisibility(prev.appToken, false);
            } else {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare open transition: prev=" + prev);
                if (mNoAnimActivities.contains(next)) {
                    anim = false;
                    mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    mWindowManager.prepareAppTransition(prev.task == next.task
                            ? TRANSIT_ACTIVITY_OPEN
                            : next.mLaunchTaskBehind
                                    ? TRANSIT_TASK_OPEN_BEHIND
                                    : TRANSIT_TASK_OPEN, false);
                }
            }
        } else {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
            if (mNoAnimActivities.contains(next)) {
                anim = false;
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
            }
        }

        Bundle resumeAnimOptions = null;
        if (anim) {
            ActivityOptions opts = next.getOptionsForTargetActivityLocked();
            if (opts != null) {
                resumeAnimOptions = opts.toBundle();
            }
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }

        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
                    + " stopped=" + next.stopped + " visible=" + next.visible);

            // If the previous activity is translucent, force a visibility update of
            // the next activity, so that it's added to WM's opening app list, and
            // transition animation can be set up properly.
            // For example, pressing Home button with a translucent activity in focus.
            // Launcher is already visible in this case. If we don't add it to opening
            // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
            // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
            final boolean lastActivityTranslucent = lastStack != null
                    && (!lastStack.mFullscreen
                    || (lastStack.mLastPausedActivity != null
                    && !lastStack.mLastPausedActivity.fullscreen));

            // 使下个 Activity 为可见
            if (!next.visible || next.stopped || lastActivityTranslucent) {
                mWindowManager.setAppVisibility(next.appToken, true);
            }

            // schedule launch ticks to collect information about slow apps.
            next.startLaunchTickingLocked();

            ActivityRecord lastResumedActivity =
                    lastStack == null ? null :lastStack.mResumedActivity;
            ActivityState lastState = next.state;

            mService.updateCpuStats();

            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
            next.state = ActivityState.RESUMED;
            mResumedActivity = next;
            next.task.touchActiveTime();
            mRecentTasks.addLocked(next.task);
            mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            mService.updateOomAdjLocked();

            // Have the window manager re-evaluate the orientation of
            // the screen based on the new activity order.
            boolean notUpdated = true;
            if (mStackSupervisor.isFocusedStack(this)) {
                Configuration config = mWindowManager.updateOrientationFromAppTokens(
                        mService.mConfiguration,
                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
                if (config != null) {
                    next.frozenBeforeDestroy = true;
                }
                notUpdated = !mService.updateConfigurationLocked(config, next, false);
            }

            if (notUpdated) {
                // The configuration update wasn't able to keep the existing
                // instance of the activity, and instead started a new one.
                // We should be all done, but let's just make sure our activity
                // is still at the top and schedule another run if something
                // weird happened.
                ActivityRecord nextNext = topRunningActivityLocked();
                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
                        "Activity config changed during resume: " + next
                        + ", new next: " + nextNext);
                if (nextNext != next) {
                    // Do over!
                    mStackSupervisor.scheduleResumeTopActivities();
                }
                if (mStackSupervisor.reportResumedActivityLocked(next)) {
                    mNoAnimActivities.clear();
                    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                    return true;
                }
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }

            try {
                // Deliver all pending results.
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                "Delivering results to " + next + ": " + a);
                        // 分发 ActivityResult 即我们常见的 onActivityResult        
                        next.app.thread.scheduleSendResult(next.appToken, a);
                    }
                }

                boolean allowSavedSurface = true;
                if (next.newIntents != null) {
                    // Restrict saved surface to launcher start, or there is no intent at all
                    // (eg. task being brought to front). If the intent is something else,
                    // likely the app is going to show some specific page or view, instead of
                    // what's left last time.
                    for (int i = next.newIntents.size() - 1; i >= 0; i--) {
                        final Intent intent = next.newIntents.get(i);
                        if (intent != null && !ActivityRecord.isMainIntent(intent)) {
                            allowSavedSurface = false;
                            break;
                        }
                    }
                    next.app.thread.scheduleNewIntent(
                            next.newIntents, next.appToken, false /* andPause */);
                }

                // Well the app will no longer be stopped.
                // Clear app token stopped state in window manager if needed.
                mWindowManager.notifyAppResumed(next.appToken, next.stopped, allowSavedSurface);

                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
                        System.identityHashCode(next), next.task.taskId, next.shortComponentName);

                next.sleeping = false;
                mService.showUnsupportedZoomDialogIfNeededLocked(next);
                mService.showAskCompatModeDialogLocked(next);
                next.app.pendingUiClean = true;
                next.app.forceProcessStateUpTo(mService.mTopProcessState);
                next.clearOptionsLocked();
        next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);

                mStackSupervisor.checkReadyForSleepLocked();

                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
            } catch (Exception e) {
                // Whoops, need to restart this activity!
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
                        + lastState + ": " + next);
                next.state = lastState;
                if (lastStack != null) {
                    lastStack.mResumedActivity = lastResumedActivity;
                }
                Slog.i(TAG, "Restarting because process died: " + next);
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
                        mStackSupervisor.isFrontStack(lastStack)) {
                    next.showStartingWindow(null, true);
                }
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }

            // From this point on, if something goes wrong there is no way
            // to recover the activity.
            try {
                completeResumeLocked(next);
            } catch (Exception e) {
                // If any exception gets thrown, toss away this
                // activity and try the next one.
                Slog.w(TAG, "Exception thrown during resume of " + next, e);
                requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                        "resume-exception", true);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null, true);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true); // 启动一个新的 Activity
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

这段代码比较多,主要逻辑是先暂停和隐藏栈中的 Activity,其中涉及到与 App 用户进程通信(暂停 Activity )和与 WindowManagerService 所在进程通信(隐藏前面的 Activity 窗口)然后调用 mStackSupervisor.startSpecificActivityLocked 启动一个新的 Activity

**[ActivityStackSupervisor.java]**
void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {

        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);
        // 该Activity所在进程已经在运行?如果有就直接启动,没有则与系统进程通信 fork出一个新的进程用来运行 Activity
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

这里有两个分支,第一个是当前 Activity 所在 app 进程没有启动,这个时候会与系统进程进行通信 fork 出一个新的进程,在新进程 main 函数中调用 ActivityManagerProxy.attachApplication 进行进程通信,最终会调用ActivityStackSupervisor.attachApplicationLocked

**[ActivityStackSupervisor.java]**
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked();
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) { //又回到之前已经有进程的分支了
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }

可以看出这里会调用 realStartActivityLocked 方法,即回到我们前面所说的第二条分支:当 Activity 所声明进程已经存在的情况

**[ActivityStackSupervisor.java]**
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

        if (!allPausedActivitiesComplete()) {
            //如果还有Activity没有完成暂停,就先跳过启动新的Activity
            return false;
        }

        if (andResume) {
            r.startFreezingScreenLocked(app, 0);
            mWindowManager.setAppVisibility(r.appToken, true);

            // schedule launch ticks to collect information about slow apps.
            r.startLaunchTickingLocked();
        }

        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.  Note that
        // as a result of this, it can call back into the activity
        // manager with a new orientation.  We don't care about that,
        // because the activity is not currently running so we are
        // just restarting it anyway.
        if (checkConfig) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            // Deferring resume here because we're going to launch new activity shortly.
            // We don't want to perform a redundant launch of the same record while ensuring
            // configurations and trying to resume top activity of focused stack.
            mService.updateConfigurationLocked(config, r, false, true /* deferResume */);
        }

        r.app = app;
        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();

        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);

        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();

        final TaskRecord task = r.task;
        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
        }

        final ActivityStack stack = task.stack;
        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
                    + " newIntents=" + newIntents + " andResume=" + andResume);
            if (andResume) {
                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
                        r.userId, System.identityHashCode(r),
                        task.taskId, r.shortComponentName);
            }
            if (r.isHomeActivity()) {
                // Home process is the root process of the task.
                mService.mHomeProcess = task.mActivities.get(0).app;
            }
            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                      PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
            r.sleeping = false;
            r.forceNewConfig = false;
            mService.showUnsupportedZoomDialogIfNeededLocked(r);
            mService.showAskCompatModeDialogLocked(r);
            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
            ProfilerInfo profilerInfo = null;
            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
                if (mService.mProfileProc == null || mService.mProfileProc == app) {
                    mService.mProfileProc = app;
                    final String profileFile = mService.mProfileFile;
                    if (profileFile != null) {
                        ParcelFileDescriptor profileFd = mService.mProfileFd;
                        if (profileFd != null) {
                            try {
                                profileFd = profileFd.dup();
                            } catch (IOException e) {
                                if (profileFd != null) {
                                    try {
                                        profileFd.close();
                                    } catch (IOException o) {
                                    }
                                    profileFd = null;
                                }
                            }
                        }

                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
                                mService.mSamplingInterval, mService.mAutoStopProfiler);
                    }
                }
            }

            if (andResume) {
                app.hasShownUi = true;
                app.pendingUiClean = true;
            }
            //将该进程设置为前台进程PROCESS_STATE_TOP
            app.forceProcessStateUpTo(mService.mTopProcessState);
            // 与 app 用户进程进行通信,启动Activity
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                // This may be a heavy-weight process!  Note that the package
                // manager will ensure that only activity can run in the main
                // process of the .apk, which is the only thing that will be
                // considered heavy-weight.
                if (app.processName.equals(app.info.packageName)) {
                    if (mService.mHeavyWeightProcess != null
                            && mService.mHeavyWeightProcess != app) {
                        Slog.w(TAG, "Starting new heavy weight process " + app
                                + " when already running "
                                + mService.mHeavyWeightProcess);
                    }
                    mService.mHeavyWeightProcess = app;
                    Message msg = mService.mHandler.obtainMessage(
                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                    msg.obj = r;
                    mService.mHandler.sendMessage(msg);
                }
            }

        } catch (RemoteException e) {
            if (r.launchFailed) {
                //第二次启动失败,则结束该activity
                Slog.e(TAG, "Second failure launching "
                      + r.intent.getComponent().flattenToShortString()
                      + ", giving up", e);
                mService.appDiedLocked(app);
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }

            //这是第一个启动失败,则重启进程重试
            app.activities.remove(r);
            throw e;
        }

        r.launchFailed = false;
        if (stack.updateLRUListLocked(r)) {
            Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
        }

        if (andResume) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            stack.minimalResumeActivityLocked(r);
        } else {
            // This activity is not starting in the resumed state... which should look like we asked
            // it to pause+stop (but remain visible), and it has done so and reported back the
            // current icicle and other state.
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to PAUSED: " + r + " (starting in paused state)");
            r.state = PAUSED;
        }

        // Launch the new version setup screen if needed.  We do this -after-
        // launching the initial activity (that is, home), so that it can have
        // a chance to initialize itself while in the background, making the
        // switch back to it faster and look better.
        if (isFocusedStack(stack)) {
            mService.startSetupActivityLocked();
        }

        // Update any services we are bound to that might care about whether
        // their client may have activities.
        if (r.app != null) {
            mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
        }

        return true;
    }

接着就利用 ApplicationThreadProxy 与 app 用户进程进行通信,进入到 app 用户端进程

用户 App 进程

**[ActivityThread.ApplicationThread]**
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
}

接着调用 sendMessage 向主线程消息队列中发送启动 Activity 的消息,辗转到 Handler的 handleMessage 方法中,其中 H 为 ActivityThread 主线程中的 Handler子类,在主线程被创建的时候创建,在 handleMessage 中会调用
handleLaunchActivity

**[ActivityThread.java]**
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        //最终回调目标Activity的onConfigurationChanged()
        handleConfigurationChanged(null, null);

        // 在创建Activity之前初始化 WMG
        WindowManagerGlobal.initialize();

        //最终会调用目标Activity的onCreate
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            //最终会调用目标Activity的onStart,onResume.
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                //如果Activity 没有销毁且不在活动状态 则暂停该Activity
                performPauseActivityIfNeeded(r, reason);
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            //如果有错误就停掉Activity
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }
**[ActivityThread.java]**
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent); //创建 Activity
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
           ...
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation); //获取Application
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity); //创建 Activity中的 mBase ContextImpl 对象
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                // 初始化Activity
                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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    //调用Activity的 onCreate方法
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
        } 
        ...
        return activity;
    }

首先通过反射创建了一个 Activity ,其次创建该 Activity 包装的 ContextImpl 对象( Activity 是一个 Context 的包装类,真正与系统资源打交道的是其包装的 ContextImpl 对象 mBase),然后通过activity.attach的函数传入参数初始化Activity,最后调用mInstrumentation.callActivityOnCreate执行到 Activity 的 onCreate 方法中,至此 Activity 整体启动流程已经走完,不过还有一个前面留下的问题,我们在这里又见到了 mInstrumentation 对象,ActivityThread 中大多操作都要倚仗它来执行,好比一个管家,跟踪它的引用可以知道它是在应用进程被创建后 BindApplication 中被创建和初始化的,一个主线程 ActivityThread 中只有一个 mInstrumentation,Activity 中 mInstrumentation 也就是主线程中的 mInstrumentation 的,其负责对内事务,而对外交流则交给 ActivityThread 负责,最后引用一张图来简述整个流程:

最后

谢谢阅读,文中如有错误欢迎交流沟通,五一快乐!
Thanks:

田维术大神的 Binder 学习指南
Android 开发艺术探索
Binder 设计与实现
老罗的博客
gityuan的博客