以Android 8.0版本为基础,以Launcher点击图标启动一个App来分析比较,这个过程需要很多次IPC,Launcher和AMS、AMS和App。
从IPC角度分析,启动流程大致为:
- Launcher与AMS进行IPC,通知AMS启动App;
- AMS做启动Activity之前的准备工作,Intent信息、LauncherMode、ActivityStack等完成后,AMS与Launcher进行IPC,通知Launcher进入后台;
- AMS检测目标Activity所在App进程是否存在,通知Zygote进程fork新进程;
- 新进程入口处
ActivityThread.main()
; - AMS通知App创建Application;
- AMS通知App创建Activity并回调相关生命周期
Launcher通知AMS启动App
Launcher本身就是一个应用,位于http://androidxref.com/8.0.0_r4/xref/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
点击桌面上的应用图标,Launcher把启动所需要的信息放到Intent,调用startActivity(),这里假设启动App之前没有打开过App。
Activity.startActivityForResult
startActivity()多个重载方法最终均调用startActivityForResult(intent, requestCode, Bundle)。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
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);
...
}
...
}
Instrumentation.execStartActivity
Activity的创建、启动和生命周期均由Instrumentation来完成。
看Instrumentation.execStartActivity()参数:
mMainThread:ActivityThread
mMainThread.getApplicationThread():ApplicationThread,ActivityThread内部类,是其他进程与App进程进行IPC的服务端。
mToken:IBinder类型,AMS端ActivityRecord.Token在App进程的本地Binder代理,具有跨进程代表Activity的能力(见Token)1
2
3
4
5
6
7
8
9
10
11
12
13
14public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token,
Activity target, Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
} catch (RemoteException e) {
}
return null;
}
ActivityManager
ActivityManager使用单例维护AMS本地代理。1
2
3
4
5
6
7
8
9
10
11
12
13public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
ActivityManager.getService()返回am,am便是AMS的本地代理了(见Binder总结)。
App进程使用AMS本地代理调用startActivity(),经过Binder驱动最终调用SystemServer进程AMS.startActivity()
。
AMS.startActivity
1 | public final int startActivity(IApplicationThread caller, String callingPackage, |
注意setMayWait(userId)
这行代码,它把mayWait
设置为true
AMS做启动Activity之前的准备工作,通知Launcher进入后台
ActivityStartController.obtainStarter
1 | ActivityStarter obtainStarter(Intent intent, String reason) { |
mFactory
:ActivityStarter内部类DefaultFactory,维护ActivityStarter对象池。
ActivityStarter.execute
1 | int execute() { |
ActivityStarter.startActivityMayWait
startActivityMayWait()
主要寻找合适的待启动Activity的参数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44private 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 globalConfig,
SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask,
String reason, boolean allowPendingRemoteAnimationRegistryLookup) {
...
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0, computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
UserManager userManager = UserManager.get(mService.mContext);
boolean profileLockedAndParentUnlockingOrUnlocked = false;
long token = Binder.clearCallingIdentity();
try {
UserInfo parent = userManager.getProfileParent(userId);
profileLockedAndParentUnlockingOrUnlocked = (parent != null)
&& userManager.isUserUnlockingOrUnlocked(parent.id)
&& !userManager.isUserUnlockingOrUnlocked(userId);
} finally {
Binder.restoreCallingIdentity(token);
}
if (profileLockedAndParentUnlockingOrUnlocked) {
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
computeResolveFilterUid(allingUid, realCallingUid, mRequest.filterCallingUid));
}
}
}
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService) {
...
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup);
...
return res;
}
}
ActivityStackSupervisor.resolveIntent
1
2
3
4
5
6
7
8 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags, int filterCallingUid) {
synchronized (mService) {
...
return mService.getPackageManagerInternalLocked().resolveIntent(
intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
...
}
}
mService.getPackageManagerInternalLocked()
返回的是PMS。
PMS.resolveIntent
1
2
3
4
5
6
7
8
9
10
11 public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) {
return resolveIntentInternal(intent, resolvedType, flags, userId, false, Binder.getCallingUid());
}
private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
int flags, int userId, boolean resolveForStart, int filterCallingUid) {
...
final ResolveInfo bestChoice = chooseBestActivity(intent, resolvedType, flags, query, userId);
return bestChoice;
...
}
mSupervisor.resolveIntent()
调用PMS处理存在多个符合Intent的Activity的情况,核心逻辑在chooseBestActivity()
中。
- 大于2个,返回ResolverActivity的ResolveInfo,弹出ResolverActivity,让用户选择启动哪个Activity,假如勾选了默认启动,下一次会直接启动默认配置的Activity;
- 1个则直接返回。(通过ResolverActivity启动Activity调用的是
AMS.startActivityAsCaller()
)
ActivityStackSupervisor.resolveActivity
主要做2件事:为Intent添加包名和类名;判断如果不是system进程则处理Debug,根据FLAG启动相应调试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, ProfilerInfo profilerInfo) {
final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
if (!aInfo.processName.equals("system")) {
if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
mService.setDebugApp(aInfo.processName, true, false);
}
if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
}
if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
}
if (profilerInfo != null) {
mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
}
}
}
return aInfo;
}
ActivityStarter.startActivity
1 | private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, |
使用调用者的IApplicationThread
和Token
去AMS分别查找到对应的ProcessRecord
和ActivityRecord
,放到新构造的ActivityRecord
中。
ProcessRecord:保存App中某一个进程的全部信息。包括当前进程的IApplicationThread的本地引用。
ActivityRecord:保存App中某一个进程的某一个Activity的全部信息。包括AMS的ActivityRecord用来跨进程标记对应Activity的Binder对象Token。
ProcessRecord和ActivityRecord均保存在AMS中,客户度可通过当前进程的ApplicationThread去AMS获取ProcessRecord,用ActivityRecord.Token获取ActivityRecord;同样的,客户端同样会保存一份ActivityClientRecord列表,ActivityClientRecord保存着AMS传来的Token的本地代理,AMS借助Token便可以在客户端ActivithThread查找指定的ActivityClientRecord并操作相应的Activity。这样通过2个BinderApp和AMS映射成功。
ActivityStarter.startActivityUnchecked
1 | private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, |
主要做了Task相关的事情,根据LaunchMode和LaunchFlags处理Task。正常启动会调用mSupervisor.resumeFocusedStackTopActivityLocked()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27//ActivityStackSupervisor
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions){
//判断重复启动,在realStartActivityLocked()被设置
if (!readyToResume()) {
return false;
}
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
return false;
}
//ActivityStack
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//判断重复启动
if (mStackSupervisor.inResumeTopActivity) { return false;}
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
...
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
ActivityStack.resumeTopActivityInnerLocked
1 | private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { |
通知Launcher进入后台
1 | private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { |
调用startPausingLocked()
处理上一个Activity也就是Launcher的暂停工作。
(点击查看)
ActivityStackSupervisor.startSpecificActivityLocked
1 | void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig){ |
判断待启动Activity所在进程是否存在,如果存在则调用realStartActivityLocked()
执行创建Activity的流程;如果进程还未创建,则首先创建新进程。
Launcher点击启动App,假设App为启动过,所以需要创建新进程。
AMS通知Zygote创建新进程
Socket通信:
服务端ServerSocket:
- 创建服务端ServerSocket并绑定端口;
- 通过调用
accept()
监听客户端请求;- 建立连接后返回连接的Socket;
- 通过Socket的输入流读取客户端发送的请求信息,通过输出流向客户端发送响应信息;
- 关闭Socket及响应资源。
客户端Socket:- 创建客户端Socket并设置连接的IP和端口;
- 建立连接后通过输入流向服务端请求信息,通过输出流读取服务端响应信息;
- 关闭Socket及响应资源。
SystemServer进程和Zygote进程:
- LocalSocketAddress:一个UNIX域的Socket地址,用于创建LocalSocket或LocalServerSocket,相当于IP及端口号;
- LocalSocket:在Unix域命名空间中创建(非服务器)Socket。此类及其返回的流支持多线程,相当于客户端Socket,由AMS创建;
- LocalServerSocket:用于在Linux抽象命名空间中创建入站UNIX域套接字的非标准类。相当于服务端Socket,由Zygote创建;
- LocalSocketImpl:完成调用native层Socket代码;
AMS.startProcessLocked
1 | final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, |
这个方法从3种情况处理新进程所对应的ProcessRecord:
从前后台进程和bad进程列表的角度;存在或不存在该进程的ProcessRecord的2种情况;系统未准备好的情况。
AMS.startProcessLocked
1 | private final boolean startProcessLocked(ProcessRecord app,String hostingType, String hostingNameStr, String abiOverride) { |
设置创建进程需要的参数,最主要是设置新进程的入口函数android.app.ActivityThread
。
AMS.startProcessLocked
1 | private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint, |
这里是异步启动进程,调用startProcess()
。
AMS.startProcess
1 | private ProcessStartResult startProcess(String hostingType, String entryPoint, |
Process.start
1 | public static final ProcessStartResult start(final String processClass, final String niceName, |
ZygoteProcess.start
1 | public final Process.ProcessStartResult start(final String processClass, final String niceName, |
方法的注释说的比较清楚:启动新的进程,然后调用processClass
这个类的main()
函数。在Zygote进程fork子进程完毕后会用到这个参数。
ZygoteProcess.startViaZygote
1 | private Process.ProcessStartResult startViaZygote(final String processClass, final String niceName, |
这里分为3个步骤:argsForZygote
: 把启动需要的参数按照顺序放到ArrayList中,因为取出也是按照顺序的;openZygoteSocketIfNeeded()
: 创建LocalSocket并连接到Zygote进程的LocalServerSocket,然后根据cpu架构返回一个ZygoteState;zygoteSendArgsAndGetResult()
: 向Zygote进程发送argsForZygote
。
先看openZygoteSocketIfNeeded()
:
ZygoteProcess.openZygoteSocketIfNeeded
1 | private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { |
mSocket & mSecondarySocket
:LocalSocketAddress;primaryZygoteState & secondaryZygoteState
:ZygoteState。封装了与Zygote进程进行Socket通信的LocalSocket和LocalSocket的输入输出流;
ZygoteState.connect
1 | public static ZygoteState connect(LocalSocketAddress address) throws IOException { |
构造LocalSocket,调用connect()
;获取用于Socket的输入流和输出流,封装到ZygoteState中。
LocalSocket.connect
1 | public void connect(LocalSocketAddress endpoint) throws IOException { |
impl
:LocalSocketImpl,通过jni调用底层Socket代码。
LocalSocket和Zygote进程的LocalServerSocket均由LocalSocketImpl实现。
SystemServer进程和Zygote进行进行通信的LocalSocket创建并连接完成,然后zygoteSendArgsAndGetResult()
是发送数据。
ZygoteProcess.zygoteSendArgsAndGetResult
1 | private static Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args) |
通过Socket的输入流输出流向Zygote进程发送创建进程的数据,然后返回进程的pid
。
再看Zygote进程如何接受Socket通信。
ZygoteInit.main
1 | public static void main(String argv[]) { |
首先调用zygoteServer.registerServerSocketFromEnv(socketName)
构造LocalServerSocket.
ZygoteServer.registerServerSocketFromEnv
1 | void registerServerSocketFromEnv(String socketName) { |
mServerSocket
:LocalServerSocket。
然后调用runSelectLoop()
,开启监听SystemServer进程中AMS发送来的消息。
ZygoteServer.runSelectLoop
1 | Runnable runSelectLoop(String abiList) { |
当有客户端Socket连接到mServerSocket
也就是LocalServerSocket时,先调用acceptCommandPeer()
方法构造ZygoteConnection,然后使用processOneCommand()
处理这个请求。
acceptCommandPeer():调用mServerSocket.accept()
拿到连接的LocalSocket,然后把这个LocalSocket和它的输入流输出流放到ZygoteConnection中。
processOneCommand():调用Zygote.forkAndSpecialize
fork子进程。
ZygoteConnection.acceptCommandPeer
1 | private ZygoteConnection acceptCommandPeer(String abiList) { |
ZygoteConnection.processOneCommand
1 | Runnable processOneCommand(ZygoteServer zygoteServer) { |
有关Linux的fork子进程的相关原理:如子进程fork成功,子进程会完全的和父进程相同,包括当前代码执行的状态。
我的理解是:
- 复制子进程之前只有一个Zygote进程,系统先暂停Zygote进程并保存当前Zygote进程快照;
- 开始创建子进程并完全拷贝Zygote进程快照;
- 子进程fork完毕后,当前除了Zygote进程还有一个与Zygote进程代码资源和运行状态完全一致的子进程,此时这个两个进程已经是彼此独立分离的;
- Zygote进程和子进程均被唤醒,Zygote进程继续往下执行返回
pid
,而子进程于Zygote进程完全一致,也被唤醒然后返回pid
,它俩完全在两条独立的分支上运行了; - Zygote进程继续监听客户端Socket的连接,而fork出来的子进程最终反射调用
ActivityThread
的main
方法。
此时代码的运行状态是:子进程返回的pid
等于0,执行handleChildProc()
;Zygote进程返回的pid
大于0,继续监听客户端Socket的消息。
ZygoteConnection.handleChildProc
1 | private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, |
ZygoteInit.childZygoteInit
1 | static final Runnable childZygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { |
RuntimeInit.findStaticMain
1 | protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) { |
findStaticMain()
返回MethodAndArgsCaller
对象,这个Runnable的run方法便是反射调用'android.app.ActivityThread'
的main
方法,这便是通常被认为的应用程序的入口。
总结:
Zygote进程孵化了SystemServer进程和相应系统服务;
SystemServer进程使用Socket向Zygote进程通信,完成新进程的创建,创建是通过fork了Zygote进程完成的;
新fork出来的进程入口处在'android.app.ActivityThread'
的main
方法。
新进程入口ActivityThread.main()
1 | public static void main(String[] args) { |
开启了主线程消息循环;
初始化ActivityThread,在ActivityThread中初始化了几个重要的变量:final ApplicationThread mAppThread = new ApplicationThread()
: 代表新进程的Binder,用于和AMS进程相护进行Binder通信,前面有解释。final H mH = new H()
:主线程Handler,处理4大组件生命周期。
调用attach()方法完成后续的工作。
ActivityThread.attach
1 | private void attach(boolean system, long startSeq) { |
初始化一些状态,然后调用mgr.attachApplication()
,把代表当前客户端进程的ApplicationThread绑定到AMS,这是因为客户端进程有关四大组件的权限控制还是要交给AMS来管理。mgr
:通过ActivityManager.getService()所获得的AMS在客户端进程的本地代理,这个本地代理具有跨进程调用AMS进程相关方法的能力。
经过Binder驱动,AMS.attachApplication()
被调用。
AMS.attachApplication
1 | public final void attachApplication(IApplicationThread thread, long startSeq) { |
thread
:客户端ApplicationThread在AMS进程的本地代理,它具有与thread
所在进程进行IPC的能力。
AMS.attachApplicationLocked
1 | private final boolean attachApplicationLocked(IApplicationThread thread, |
检查thread所在进程相对应AMS中保存的ProcessRecord信息是否有异常;
重置ProcessRecord的状态并绑定客户端进程的IApplicationThread本地代理;
移除创建进程超时的message;
如果该进程存在需要启动的ContentProvider,则发送一个延时10s的ANR消息;
创建客户端进程的Application;
处理Activity、Service和BroadcastReceiver系统组件。
AMS通知App创建Application
AMS调用thread.bindApplication()
,经过Binder驱动,最终客户端进程的ApplicationThread.bindApplication()
被调用;
ApplicationThread.bindApplication
1 | public final void bindApplication(String processName, ApplicationInfo appInfo, |
sendMessage(H.BIND_APPLICATION, data)
发送BIND_APPLICATION
消息到mH
,然后在主线程中调用ActivityThread.handleBindApplication()
;
ActivityThread.handleBindApplication
1 | private void handleBindApplication(AppBindData data) { |
调用getPackageInfoNoCheck()
创建LoadedApk,LoadedApk是内存形式的.apk
文件;
创建Instrumentation;
使用LoadedApk创建Application;
调用Instrumentation回调Application的onCreate()
方法。
LoadedApk.makeApplication
1 | public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) { |
检查是否创建过Application;得到Application类名、ContextImp和ClassLoader,然后借助Instrumentation去构造Application;最后把Application缓存起来;
接着看Instrumentation.newApplication()
:
1 | public Application newApplication(ClassLoader cl, String className, Context context) |
getFactory()
:AppComponentFactory,它是用于管理manifest文件中的Application和4大组件实例化的接口。
看AppComponentFactory.instantiateApplication()
。
1 | public Application instantiateApplication(ClassLoader cl, String className) |
最终Application通过反射的方式生成了,然后attach()
被调用,当使用LoadedApk创建Application完毕后,回到ActivityThread.handleBindApplication
,紧接着调用Instrumentation.callApplicationOnCreate()
回调Application的onCreate()
方法。
Instrumentation.callApplicationOnCreate
1 | public void callApplicationOnCreate(Application app) { |
很简洁!
AMS进程和客户端进程进行IPC;
客户端进程创建LoadedApk和Instrumentation;
使用LoadedApk创建Application;
调用Instrumentation回调Application的onCreate()
方法。
AMS通知App创建Activity并回调相关生命周期
回到AMS.attachApplicationLocked()
,AMS通知客户端进程创建完Application之后,调用mStackSupervisor.attachApplicationLocked()
处理Activity:
ActivityStackSupervisor.attachApplicationLocked
1 | boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { |
从后向前遍历当前显示屏幕上的Activity栈,如果这个栈没有焦点则跳出循环;
遍历这个栈中所有的ActivityRecord,判断ActivityRecord是否绑定了ProcessRecord、uid是否相同、进程名是否相同;
如果这3个条件都满足,则取出这个栈的栈顶处于运行状态的ActivityRecord,调用realStartActivityLocked()
方法启动Activity。app
:客户端进程中对应的ProcessRecord;activity
:客户端进程中待启动Activity对应的ActivityRecord。andResume
:true,启动后进行resume操作。
ActivityStackSupervisor.realStartActivityLocked
1 | final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, |
Activity的启动和运行,AMS通过事务的统一发送到客户端进程。这个过程类似于AMS发送事务让Launcher进入后台执行pause操作,经过Binder驱动,最终来到客户端进程,由客户端进程中ActivityThread的TransactionExecutor
来处理AMS发送的ClientTransaction
。
TransactionExecutor先后处理ClientTransaction
的mActivityCallbacks
和mLifecycleStateRequest
,其中mActivityCallbacks
便是LaunchActivityItem,作用是创建Activity并回调onCreate()
方法;
先看LaunchActivityItem:
LaunchActivityItem.execute
1 | public void execute(ClientTransactionHandler client, IBinder token, |
client
:ActivityThread父类,定义了抽象方法由ActivityThread实现;token
:AMS进程中,是代表Activity的ActivityRecord所保存的Token
(Binder)在客户端进程的本地代理,
构造ActivityClientRecord,调用ActivityThread.handleLaunchActivity()
。
ActivityThread.handleLaunchActivity
1 | public Activity handleLaunchActivity(ActivityClientRecord r , |
ActivityThread.performLaunchActivity
1 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
Instrumentation.newActivity()
:类似Application的创建,最终调用AppComponentFactory.instantiateActivity()
反射构造Activity;activity.attach()
:Activity自己的初始化;mInstrumentation.callActivityOnCreate()
:先调用activity.performCreate()
,再回调Activity.onCreate()
。
分析完了LaunchActivityItem如何创建Activity并回调onCreate()
方法后,再看TransactionExecutor如何处理ClientTransaction的mLifecycleStateRequest
。
通过前面的文章分析知道,TransactionExecutor再处理ClientTransaction时,会通过cycleToPath()
以及performLifecycleSequence()
方法,处理当前声明周期状态到目标声明周期中间的声明周期,在LaunchActivityItem处理完毕后,当前状态是ON_CREATE
,而目标状态是ON_RESUME
,所以cycleToPath()
会在处理ResumeActivityItem前先调用ActivityThread.handleStartActivity()
完成Activity的onStart()
方法的回调。处理完cycleToPath()
以后,TransactionExecutor再处理ResumeActivityItem,ResumeActivityItem最终回调Activity的onResume()
方法,具体的流程不在分析。
(点击查看)
这个时候Activity便显示出来了。
总结
- 分析Activity启动过程更多的是分析SystemServer进程的AMS和客户端进程之间的通信。包括Launcher进程、AMS进程、待启动App进程。
- 有2个重要的Binder贯穿了这个通信过程。首先是AMS为Activity创建的ActivityRecord的内部类Token,它被保存在ActivityRecord中,ActivityRecord被保存在AMS中,当Token传递到客户端进程中时,又被客户端进程的ActivityThread保存起来;然后是客户端进程被fork出来后,ActivityThread的内部类ApplicationThread,它代表着当前进程用来和其他系统进程进行通信,ApplicationThread的本地代理随后被保存到AMS中。这样AMS通过ApplicationThread的本地代理控制着客户端进程,而客户端处理问题则带着保存的Token本地代理再传给AMS,让AMS查找到对应的ActivityRecord。
- AMS进程通过Socket和Zygote进程通信,进行fork子进程的操作,子进程fork成功后,回调用
ActivithThread.main()
。 - 有关Activity的启动模式和FLAG均由AMS处理,在
ActivityStarter.startActivityUnchecked()
中。 - 下一个Activity的显示必须等到上一个Activity执行完onPause()。
- 如果待启动Activity的进程已经存在,则在
ActivityStackSupervisor.startSpecificActivityLocked()
时,直接调用ActivityStackSupervisor.realStartActivityLocked()
,省略创建进程的步骤了。 - 是Zygote进程创建了SystemServer进程,见
ZygoteInit.main()
中执行的forkSystemServer()
方法。 - 以后再补充。。。
最后来一张完整图片来概括整个过程:
(点击查看大图)