直观流程图

具体流程分析
- Activity调用startActivity,虽然startActivity有很多重载函数,但是最终也会调用Activity中的startActivityForResult方法,在startActivityForResult中有一个mParent的null判断,mParent代表的是ActivityGroup,ActivityGroup用于在一个Activity中放入多个子Activity,已经被废弃,使用Fragmemt和FragmentManager替代,所以主要看mParent==null
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//调用Instrumentation的execStartActivity方法
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
//返回结果不为空,证明返回的intent中含有参数,将参数作为结果返回
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
....忽略
}
}
- 在Instrumentation.execStartActivity方法代码,具体关注ActivityManager.getService().startActivity方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
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;
}
上面这段代码中,可以发现启动Activity真正的实现由ActivityManager.getService()的startActivity方法完成,ActivityManager.getService()方法其实是一个IActivityManager类型的Binder对象,这个Binder对象使用一个单例模式进行封装,保证全局只有一个IActivityManager对象.
在执行完 ActivityManager.getService().startActivity方法后,还有一句checkStartActivityResult(result , intent);这句代码就是用于检查启动的Activity的结果,当无法正常启动Activity的时候,就会抛出异常,其中最常见的一个异常信息就是
Unable to find explicit activity class ** have you declared this activity in your AndroidManifest.xml?
- 通过上面的流程分析,现在发现具体的Activity启动主要就是在AMS中的startActivity方法.AMS中的startActivity又调用了startActivityAsUser方法,这里又将Activity的启动转移到了ActivityStarter的startActivityMayWait方法中,
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
...
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
- 饶了一大圈其实就是在ActivityStarter内部,ActivityStack,ActivityStackSupervisor之间不断调用,最终落在ActivityStackSupervisor的realStartActivityLocked方法中,其中注意方法中以下代码
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, // override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
scheduleLaunchActivity这个方法是在realStartActivityLocked中被调用的,app.thread对象是IApplicationThread,这个IApplicationThread是一个IBinder对象,这个接口的实现类在ActivityThread中,一个私有的内部类,ApplicationThread ,该类继承自IApplicationThread.Stub,实现了IApplicationThread所有的抽象方法.
scheduleLaunchActivity就是启动Activity的方法,通过发送一个启动activity的消息交给handler处理,handler接收到消息后调用handleLaunchActivity方法,然后调用了handleResumeActivity方法调用被启动的Activity的onResume生命周期方法.
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) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
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, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
handleLaunchActivity中调用了performLaunchActivity和handleResumeActivity方法
- 在performLaunchActivity中,通过调用了Instrumentation的newActivity方法,通过反射创建了Activity对象,调用LoadedApk中的makeApplication创建了Application对象,其内部实现也是通过反射.
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
忽略部分初始化代码...
//创建Context的实现类
ContextImpl appContext = createBaseContextForActivity(r);
//创建Activity对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
...
//创建Application对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
//Activity与Context建立联系,同时完成Activity与Window的关联.
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, window, r.configCallback);
}
Activity的启动流程大体如此,大部分逻辑都是参考<<Android开发艺术探索>>,但是由于书中的源码版本是Android5.0,而我在学习的时候使用的源码是Android8.0,所以可能会有部分代码有出入,但是整体结构和逻辑都是一样的,并不影响对Activity启动的掌握
网友评论