Activity的启动流程
本文是我通过阅读android sdk源码了解到的activity启动的流程,如有不足之处,望告知。
下面是activity启动时的函数流程
- Activity.java
1.public void startActivity(Intent intent)
2.public void startActivity(Intent intent, Bundle options)
3.public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options)
- Instrumentation.java
4.public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target,Intent intent, int requestCode, Bundle options)
- ActivityManagerService.java
5.public int startActivity(IBinder whoThread, String callingPackage, Intent intent, String resolvedType, Bundle options)
6.public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)
7. 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)
- ActivityStackSupervisor.java
8. final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage,
int realCallingPid, int realCallingUid, int startFlags, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[]outActivity,
ActivityContainer container, TaskRecord inTask)
9. final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask)
10. boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions)
- ActivityStack.java
11. final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options)
12.private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options)
- ActivityStackSupervisor.java
13. void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)
14. final boolean realStartActivityLocked(ActivityRecord r,ProcessRecord app, boolean andResume, boolean checkConfig)
- ActivityThread.java
15. 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)
- ActivityThread$H.java
16.public void handleMessage(Message msg) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
17.private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent)
18.private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
19.private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity)
- Activity.java
20.final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor)
- ContextThemeWrapper.java
21.public void setTheme(int resid)
- Instrumentation.java
22. public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState)
- Activity.java
23. final void performCreate(Bundle icicle)
以上便是一个activity启动的所有流程,我下面将重点挑出其中几个步骤来进行解析。
- 在第3步中
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
在调用 mInstrumentation.execStartActivity(····)方法时,传入的第二个参数是位于ActivityThread中的一个ApplicationThread对象,他是Binder的一个子类,后文将提到他如何使用。
- 在第4步中
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
···
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.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()是个单例的binder对象。ActivityManagerService是ActivityManagerNative的子类,他继承了这个单例对象,ActivityManagerNative.getDefault()用于与ActivityManagerService之间的通信。
- 在第4-8步这个执行过程中,系统一直将在第三步中传入的ApplicationThread对象一直原封不动的传递,直到第8步中
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage,
int realCallingPid, int realCallingUid, int startFlags, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
```
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, this, container, options);
```
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
if (err < 0) {
// If someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
// switch... just dismiss the keyguard now, because we
// probably want to see whatever is behind it.
notifyActivityDrawnForKeyguard();
}
return err;
}
得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了。将其封装到一个ActivityRecord 对象中,ActivityRecord 对象是Activity的标识,与每个Activity是一一对应的
- 在第13步中
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
首先利用activity的信息获取进程记录块。
- 在第14步中
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
```
if (andResume) {
app.hasShownUi = true;
app.pendingUiClean = true;
}
app.forceProcessStateUpTo(mService.mTopProcessState);
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
````
}
利用在上一步中得到的ProcessRecord获取与ActivityThread之间通信的binder,向ActivityThread发出准备启动activity的消息。
- 在收到scheduleLaunchActivity消息后,ActivityThread类里面执行scheduleLaunchActivity方法,
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);
}
先将要启动的activity的信息放入位于ActivityThread的静态内部类ActivityClientRecord 中,然后这里的sendMessage方法是经过封装后的mH变量的sendMessage方法,mH是一个位于ActivityThread中的Handler,然后接着向下执行。
- 在第18步中
ComponentName component = r.intent.getComponent();
先获取一开始用于构造StartActivity中的intent的activity类名、
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
通过类加载器将该Activity加载进来并实例化他的对象。
Context appContext = createBaseContextForActivity(r, activity);
创建该Activity的contextimpl对象,用于给ContextWrapper中的mBase变量赋值
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);
attach时就是将各种activity中的各种信息赋给已经实例化好的Activity空对象
在第21步中
就是给已经实例化好的activity对象设置主题以及一些资源在第22-23步中
调起Activity的oncreate方法,这样一个Activity的完全加载到了我们的视野里面,到这里,Activity的启动就结束了,后面则是Activity自己的生命周期。