根Activity的启动过程简述
参照《Android系统源代码情景分析》中的例子。
有三个Activity:
1. MainActivity 根Activity
2.SubActivityInProcess 与根Activity运行在同一个进程的Activity
3.SubActivityInNewProcess 运行在新进程中的Activity
两个重要的结构体:
1.ActivityRecord 每个启动的Activity在ActivityManagerService中都有唯一一个对应的ActivityRecord对象。该对象是Binder本地对象。同时Activity所在的ActivityThread会持有该ActivityRecord的binder代理对象。在Activity和ActivityManagerService进行远程通信的时候,该binder代理对象会被传输以被ActivityManagerService用来识别当前与自己通信的Activity的具体信息。
2.ApplicationThread 每个app都含有这样一个Binder本地对象。每个运行的app进程在ActivityManagerService中都有一个唯一的ProcessRecord对象。该对象保存了ApplicationThread的Binder代理对象。从而ActivityManagerService可以主动与Activity所在的进程进行通信。
3.ActivityClientRecord 每个启动的Activity在自身进程中都有唯一一个对应的ActivityClientRecord对象。它和Activity进程所持有的ActivityManagerService中的ActivityRecord的代理对象是一一对应的。
重要变量:
ActivityStack类有三个成员变量mResumedActivity, mLastPausedActivity和mPausingActivity,它们的类型均为ActivityRecord,分别用来描述系统当前激活的Activity组件、上一次被中止的Activity组件,以及正在被中止的Activity组件。
从Launcher启动MainActivity
1.Launcher-->startActivitySafely
2.Activity-->startActivity
3.Activity-->startActivityForResult
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode
);
mMainThread.getApplicationThread()就是Launcher Activity所属进程的ApplicationThread本地对象。
mToken是Launcher Activity在ActivityManagerService中的ActivityRecord对应的代理对象。
4.Instrumentation-->execStartActivity
5.ActivityManagerProxy-->startActivity
将需要启动的intent信息以及自身的一些信息写入Parcel中进行远程通信
...
//caller是IApplicationThread
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
//intent是需要启动的MainActivity的相关信息
intent.writeToParcel(data, 0);
//resultTo是Launcher Activity对应的ActivityRecord代理对象
data.writeStrongBinder(resultTo);
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
...
接下来在ActivityManagerService进程中执行
6.ActivityManagerService-->startActivity
7.ActivityStack-->startActivityMayWait
通过PackageManager解析需要启动的intent信息,获取对应的ActivityInfo
ActivityInfo aInfo;
ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent(intent, resolvedType, PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS);
aInfo = rInfo != null ? rInfo.activityInfo : null;
8.ActivityStack-->startActivityLocked
通过Launcher传过来的ActivityRecord代理对象获取其在ActivityManagerService中对应的ActivityRecord sourceRecord
通过Launcher传过来的IApplicationThread对象获取Launcher进程在ActivityManagerService中对应的ProcessRecord对象 callerApp,以及进程id callingPid和用户id callingUid。
用callerApp callingUid以及第7步得到的aInfo构造需要启动的MainActivity对应的ActivityRecord r。
9. ActivityStack-->startActivityUncheckedLocked
检测到MainActivity所在的Task不存在,新建一个TaskRecord。将该TaskRecord赋给MainActivity对应的ActivityRecord的task变量中。并将该TaskRecord加入到ActivityManagerService的recentTask中。
ActivityStack-->startActivityLocked
将MainActivity对应的ActivityRecord加入到ActivityStack的mHistory中。
10.ActivityStack.resumeTopActivityLocked
获取当前运行的top Activity的ActivityRecord(就是MainActivity)。和mResumedActivity(即Launcher Activity)相比较。发现不一致。于是需要告诉mResumedActivity需要执行pause操作。
11.ActivityStack-->startPausingLocked
通过Launcher Activity对应的ActivityRecord所保存的ProcessRecord的thread对象获取Launcher Activity所在进程的IApplicationThread代理对象。从而进行远程通信。
//prev是Launcher Activity对应的ActivityRecord。 app是ProcessRecord类型。thread是IApplicationThread类型。
prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, prev.configChangFlags);
同时发送一个PAUSE_TIMEOUT_MSG延迟消息。如果PAUSE_TIMEOUT时间之后这个消息没有被取消掉,说明Launcher Activity的pause操作无响应了。
12.ApplicationThreadProxy.schedultePauseActivity
...
//token是Launcher Activity对应的ActivityRecord
data.writeStrongBinder(token)
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
...
接下来在Launcher Activity的进程中执行
13.ApplicationThread-->schedulePauseActivity
14.ActivityThread-->queueOrSendMessage
15.H-->handleMessage
16.ActivityThread-->handlePauseActivity
//token是Launcher Activity的ActivityRecord代理对象。
Bundle state = performPauseActivity(token, finished, true);
17. ActivityManagerProxy-->activityPaused
...
//token是Launcher Activity的ActivityRecord代理对象
data.writeStrongBinder(token);
data.writeBundle(state);
mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
...
接下来在ActivityManagerService进程中执行
18.ActivityManagerService-->activityPaused
19.ActivityStack-->activityPaused
移除之前发送的PAUSE_TIMEOUT_MSG延时信息
修改Launcher Activity的ActivityRecord的状态。
int index = indexOfTokenLocked(token);
ActivityRecord r = mHistory.get(index);
20. ActivityStack-->completePauseLocked
将mPausingActivity置为null
21.ActivityStack-->resumeTopActivityLocked
上一次进入这个函数的时候由于resumedActivity不等于top running Activity.所以进入了pause流程。
这次由于已经pause过了。所以直接进入start流程。
22.ActivityStack-->startSpecificActivityLocked
检测到MainActivity对应的进程并没有起来。也即MainActivity对应的ActivityRecord的app (ProcessRecord类型)以及app.thread(IApplicationThread类型)为null。启动进程。
23.ActivityManagerService.startProcessLocked
为MainActivity所在进程创建ProcessRecordLocked对象。启动进程
int[] gids = mContext.getPackageManager().getPackageGids(app.info.packageName);
int pid = Process.start("android.app.ActivityThread", mSimpleProcessManageMent ? app.processName : null, uid, uid, gids, debugFlags, null);
发送一个延时消息PROC_START_TIMEOUT_MSG,如果PROC_START_TIMEOUT之后,该消息没有被取消。则判断为启动进程无响应。
接下来在MainActivity的进程中运行
24.ActivityThread-->main
创建ActivityThread。创建ApplicationThread。
25.ActivityManagerProxy-->attachApplication
//app是IApplicationThread类型
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
接下来在ActivityManagerService的进程中运行
26.ActivityManagerService.attachApplication
27.ActivityManagerService.attachApplicationLocked
通过Binder驱动告知的pid获取当前attach的进程在ActivityManagerService中对应的ProcessRecord。第23步创建的。
将ApplicationThread代理对象保存在ProcessRecord中。供之后ActivityManagerService与Activity进程通信用。
移除之前发送的延迟消息PROC_START_TIMEOUT_MSG
检测到top running Activity需要运行,且其ActivityRecord的app为null,且进程名等于当前attach的进程名。于是启动MainActivity.
28.ActivityStack.realStartActivityLocked
ProcessRecord有activities变量保存有所有在该进程中运行的Activity
29.ApplicationThreadProxy-->scheduleLaunchActivity
...
//intent是MainActivity的intent
intent.writeToParcel(data, 0);
//token是MainActivity对应的ActivityRecord本地对象
data.writeStrongBinder(token);
//info是MainActivity对应的ActivityInfo
info.writeToParcel(data, 0);
mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
...
接下来是在MainActivity的进程中运行的
30.ApplicationThread-->scheduleLaunchActivity
为MainActivity创建ActivityClientRecord。将其和ActivityRecord关联起来。
31.ActivityThread-->queueOrSendMessage
32.H-->handleMessage
调用ActivityThread类的getPackageInfoNoCheck获取LoadedApk对象。赋给ActivityClientRecord的packageInfo成员变量中。
33.ActivityThread-->handleLaunchActivity
34.ActivityThread.performLaunchActivity
调用Instrumentation.newActivity创建MainActivity的实例。
创建MainActivity的Application。
为MainActivity的实例赋予需要用到的变量。
35.MainActivity.onCreate