当我们启动一个Activity,都将通过startActivityForResult去开始Activity的启动过程。
1. startActivityForResult方法(Activity.java)
在startActivityForResult方法中一个重要方法execStartActivity
execStartActivity方法就像一个魔盒,后续的启动过程跟它的调用者、参数都息息相关
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);
...
}
...
}
2. execStartActivity方法(Instrumentation.java)
- 在execStartActivity方法中启动Activity的实现交由ActivityManager.getService()的startActivity方法完成。ActivityManager.getService()得到的就是AMS(ActivityManagerService),是一个Binder。
- 并且会调用checkStartActivityResult方法检查启动结果
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.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;
}
3. 由此启动过程转移到AMS的startActivity中
此方法中会调用一系列方法。最终以ActivityStackSupervisor的realStartActivityLocked方法为启动的关键方法,继续启动过程
4. realStartActivityLocked方法(AMS ---->ActivityStackSupervisor.java)
在此方法中调用这样的一段代码app.thread.scheduleLaunchActivity(),并把AMS这边对这个Activity的记录各方面信息当做参数,这样客户端就能获取到Activity的各种信息即ActivityClientRecord。
- app.thread实际就是ActivityThread的内部类ApplicationThread。也就是调用execStartActivity方法传递的参数mMainThread.getApplicationThread()
- 由此启动过程从服务又回到客户端了
//ActivityStack类
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
//...
try {
//...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration),
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
//...
} catch (RemoteException e) {
//...
}
//...
return true;
}
5. scheduleLaunchActivity() (ActivityThread.java)
这个方法保存Activity相关信息后,完成一件事:向名为H的Handler发送一条启动消息,接下来Handler H将对“LAUNCH_ACTIVITY”这个消息进行处理,交由handleLaunchActivity方法实现。
//ActivityThread类
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
6. handleLaunchActivity方法(ActivityThread.java)
由H Handler处理消息也意味着启动过程到了主线程中
- 此方法中将调用performLaunchActivity方法最终完成Activity对象的创建和启动过程
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
7. performLaunchActivity方法(ActivityThread.java)
完成以下几件事
- 从ActivityClientRecord中获取待启动Activity组件的信息
- 通过Instrumentation的newActivity方法使用类加载器创建Activity对象
- 通过LoadedApk的makeApplication方法尝试创建Application对象
- 创建ContextImpl对象并通过attach方法来完成一些重要数据的初始化(由attach方法ContextImpl与Activity建立关联)
- 调用Activity的onCreate方法
这样就完成了整个启动过程
- 新的Activity何时被创建
- Activity的onCreate方法何时被系统回调?
https://www.jianshu.com/p/4edf1987a940
网友评论