Activity的启动流程

725 阅读3分钟

1、向AMS发startActivity请求

startActivity会通过binder调用到AMS,拿到AMS的Binder对象,通过mRemote的transact函数把请求发出去。transact将所有的请求参数封装到一个Parcel里面,就是data,然后写到Binder驱动,Binder驱动再转发到AMS,AMS就能收到一个transact回调,将所有的请求参数从data里取出来,再根据请求码来处理请求,如下图

2、AMS如何处理startActivity

首先查询Activity对应的进程启动了没,主要看ProcessRecord是否存在并且应用是否向AMS注册过自己的ApplicationThread,如果都满足,调用realStartActivityLocked启动Activity,如果不满足,先启动进程,调用startProcessLocked,进程启动完后,再启动Activity 在startProcessLocked中有一个entryPoint,是应用启动后的入口函数的java类。Process.start会向Zygote发送一个启动进程的请求,这个进程启动后就知道执行哪个类的入口函数。Zygote在启动完进程后会返回进程的Pid,放在Process.ProcessStartResult里,往mPidsSelfLocked里面添加一条Pid为key,ProcessRecord为value的记录。再发送一条延迟消息,如果应用进程再启动后,一定时间没有向AMS报告,就会超时,超时时间10s,超时后AMS会清理应用的相关信息,如准备启动的一些应用组件。 startViaZygote做了两件事,一是打开通往Zygote的socket,二是通过socket发送启动进程参数,然后再读取返回结果。Zygote端的处理是在runOnce函数里,首先读取AMS发过来的参数列表,然后创建子进程,父进程把子进程的Pid通过Socket返回给AMS。子进程通过handleChildProc做一些通用的初始化,比如启动Binder机制,调用应用的入口函数,就是ActivityThread的main函数

下面看Activity的入口函数,先准备好主线程的Looper,然后创建ActivityThread对象,通过attach函数向AMS注册,AMS向Zygote发启动进程请求会等待应用进程向它报到,如果10s未报到会清理。attach的实现是一个跨进程调用,首先拿到AMS Binder对象,然后调用它的attachApplication,参数为应用端的binder对象,这样AMS拿到后就可以调用应用端。 根据Pid到map里面查ProcessRecord,然后通过应用端注册到AMS的binder对象调用bindApplication,让应用去做一些初始化,比如创建Application,然后处理因应用进程未启动而挂起的应用组件。 拿到管理应用的mFocusedStack,调用topRunningActivityLocked函数,从stack里找到最近的task,取出这个task栈顶的Activity,启动Activity。 app是ProcessRecord对应应用进程,thread对应binder对象,是应用启动时注册到AMS,现在AMS通过这个binder对象向应用发起Binder调用,就是scheduleLanchActivity,应用加载Activity,应用封装了一个消息丢到主线程。 LoadedApk保存了Apk的信息,之后创建Activity会用到classLoader去加载Apk里的Activity类, 生成appContext后把它attach给Activity,给Activity赋予上下文,attach里面还有初始化工作。 onResume生命周期如下 总的来说就是 除了AMS和Zygote是Socket通信之外,其余全是Binder通信