赞
踩
每个Android开发者都知道,可以用startActivity()
或者startActivityForResult()
来启动一个Activity。那么startActivity()
这个方法到底是通过什么样的调用流程来启动Activity的呢?
下面我们从源码的角度来看一下调用流程:
客户端:和各个App紧密相关的部分,比如Activity
、ActivityThread
、ApplicationThread
,也就是常说的系统应用层。
服务端:统一管理各个应用的系统类。比如ActivityManagerService
、PackageManagerService
等,也就是我们常说的FrameWork层。这些服务都是被所有的App公用的,当某个App想实现某个操作的时候,要告诉这些系统服务。
客户端与服务端通讯:客户端和服务端分属于不同的进程,他们之间的通讯是通过bundle
来进行通讯的。比如启动一个Activity时,客户端会通过调用本地的一个代理方法,来把启动Activity的信息传递给服务端,服务端收到此信息后,经过一系列方法后,也会调用服务端的代理方法,告诉客户端可以显示了。
Activity
、Service
等系统组件。一个App启动时候会创建一个ActivityThread
,每个App也只有一个ActivityThread。由于整个流程的方法调用比较多,所以这里画了一个调用流程。图比较大,大家可以点击去看大图:
这里主要从源码的角度出发,带领大家过一遍整体的方法调用流程。
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// 默认会调用startActivityForResult(intent,-1)的方法
startActivityForResult(intent, -1);
}
}
可以看出,不论怎样都会调用startActivityForResult()
方法,所以用这种方式startActivityForResult(intent,RESULT_OK)
启动一个Activity的话,是收不到任何回传的值的。
startActivityForResult
方法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);
} else {
//...
}
}
startActivityForResult
会调用Instrumentation
中的execStartActivity()
方法。
Instrumentation
这个类就是完成对Application和Activity初始化和生命周期的工具类。每个Activity
都持有Instrumentation
对象的一个引用,但是整个进程只会存在一个Instrumentation
对象,着个Instrumentation
对象存放在ActivityThread
中。
execStartActivity()
方法:public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { //... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); //主要是这段代码,可以看出这里会获取Service,然后调用startActivity方法 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; }
就如上面注释中说明的那样execStartActivity()
会通过ActivityManager.getService()
获取一个类,来调用startActivity()
方法。
那么这个类是什么呢?我们继续往下看:
//这里会调用下面成员变量的方法
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//可以看出,这里创建了一个IActivityManager.Stub的实现类,也就是客户端代理类
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
接下来我们可以看看Singleton
的get()
方法
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
//get方法会返回对应的泛型,也就是上段代码中onCreate创建的IActivityManager的实现类
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
从Binder
机制来说,客户端有个基于IActivityManager.Stub
代理类,那么这个代理类会调用服务端的,同样实现了这个接口的类的对应的方法。然后去服务端查看,发现ActivityManagerService
果然实现了IActivityManager.Stub
类。
所以,这个ActivityManager.getService().startActivity()
的调用,会通过Binder
机制,调用到ActivityManagerService
的startActivity()
方法。也就完成了客户端与服务端的交流。
再从startActivity()
开始
上一段客户端的流程结束后,我们的启动流程走到了ActivityManagerService.startActivity()
方法,接下来看一下这个方法干了些什么:
@Override public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { //... //这里调用当前类的startActivityAsUser方法 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } @Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, //... //这里调用ActivityStarter的startActivityMayWait方法 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null, "startActivityAsUser"); }
跟着代码,我们到达了ActivityStarter
类,这个类负责处理Activity
的Intent
和Flags
的逻辑, 还有管理Stack
和TaskRecord
。
ActivityStarter.startActivityMayWait()
方法: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 globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask, String reason) { //... // 通过PKMS 查找匹配该Intent的ActivityInfo。 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); //... //获取调用者的pid 和 uid synchronized (mService) { //...此处省略100行代码 //启动Activity的核心函数startActivityLocked int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask, reason); //... 此处省略120行左右代码 return res; } }
这里可以看到,startActivityMayWait
会调用startActivityLocked
方法来继续启动Activity
。
startActivityLocked
方法int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, TaskRecord inTask, String reason) { //... //在哪android8.0中,这里单独提取了一个startActivity方法,来处理各种逻辑, //且这个方法只会在这里调用 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, container, inTask); //... return mLastStartActivityResult; }
startActivity()
方法private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, TaskRecord inTask) { //...省略了三百来行 //下一步查看这个方法 doPendingActivityLaunchesLocked(false); //这里调用的也是下面的startActivity方法 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask, outActivity); } //跟进到这里: final void doPendingActivityLaunchesLocked(boolean doResume) { //... //再次调用另一个startActivity方法 startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null, null /*outRecords*/); //... } //继续跟进 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { //... result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); //... return result; }
startActivityUnchecked()
方法private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { //1. 初始化环境和lunchModeFlags setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor); computeLaunchingTaskFlags(); computeSourceStack(); mIntent.setFlags(mLaunchFlags); //2. 复用activity逻辑 ActivityRecord reusedActivity = getReusableIntentActivity(); //... //3.singleTop 或者singleInstance的处理 if (dontStart) { ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.getTask()); // For paranoia, make sure we have correctly resumed the top activity. topStack.mLastPausedActivity = null; if (mDoResume) { //*********************************************** mSupervisor.resumeFocusedStackTopActivityLocked(); } ActivityOptions.abort(mOptions); if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { // We don't need to start a new activity, and the client said not to do // anything if that is the case, so this is it! return START_RETURN_INTENT_TO_CALLER; } top.deliverNewIntentLocked( mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); // Don't use mStartActivity.task to show the toast. We're not starting a new activity // but reusing 'top'. Fields in mStartActivity may not be fully initialized. mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId, preferredLaunchDisplayId, topStack.mStackId); return START_DELIVERED_TO_TOP; } //... //4. 设置对应task并带到前台 int result = START_SUCCESS; if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { newTask = true; result = setTaskFromReuseOrCreateNewTask( taskToAffiliate, preferredLaunchStackId, topStack); } else if (mSourceRecord != null) { result = setTaskFromSourceRecord(); } else if (mInTask != null) { result = setTaskFromInTask(); } else { // This not being started from an existing activity, and not part of a new task... // just put it in the top task, though these days this case should never happen. setTaskToCurrentTopOrCreateNewTask(); } if (result != START_SUCCESS) { return result; } //... //5. 启动Activity mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions); //6. 使Activity可见 if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); mWindowManager.executeAppTransition(); } else { if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked"); } //*********************************************** mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } else { mTargetStack.addRecentActivityLocked(mStartActivity); } //... return START_SUCCESS; }
如注释中所示,这个方法主要负责让Activity
显示出来。在启动Activity
之后我们需要经过一些调用来使Activity
可见,这时会调用上面代码中*
下面的方法,也就是resumeFocusedStackTopActivityLocked()
ActivityStackSupervisor
类中的resumeFocusedStackTopActivityLocked
方法:boolean resumeFocusedStackTopActivityLocked() { return resumeFocusedStackTopActivityLocked(null, null, null); } boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (targetStack != null && isFocusedStack(targetStack)) { //发现调用的ActivityStack中的方法 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || r.state != RESUMED) { //同样调用的ActivityStack中的方法 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); } else if (r.state == RESUMED) { // Kick off any lingering app transitions form the MoveTaskToFront operation. mFocusedStack.executeAppTransition(targetOptions); } return false; }
这个方法有调用了的ActivityStack
中的方法resumeTopActivityUncheckedLocked
,我们继续跟进:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { //... boolean result = false; try { //... //继续跟进此方法 result = resumeTopActivityInnerLocked(prev, options); } finally { mStackSupervisor.inResumeTopActivity = false; } //... return result; } //继续跟进 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { //... //此方法中代码巨多,我们暂时先关心这行: mStackSupervisor.startSpecificActivityLocked(next, true, true); //... return true; }
上述代码有回调到了ActivityStackSupervisor
类中,所以我们继续进入查看
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { //... if (app != null && app.thread != null) { //... //看方法,我们好像终于找到真正的启动点了 //跟进这个方法 realStartActivityLocked(r, app, andResume, checkConfig); return; //... } //... } //继续跟进 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { //省略大约两百行代码 //这里终于看上去像是回调客户端了,没错,他就是回调客户端的方法 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global and // override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); //... return true; }
变量app
是一个ProcessRecord
对象,它的成员变量thread
是IApplicationThread
类型,因此app.thread
是一个IApplicationThread的代理对象。
和之前客户端调用服务端类似,通过Binder机制,会使ApplicationThread$scheduleLaunchActivity
方法被调用。
于是,基于Binder
机制,又实现了一次进程间的通信,将启动Activity
的操作交给了ActivityThread
的内部类ApplicationThread
类。
ApplicationThread.schedulelaunchActivity()
private class ApplicationThread extends IApplicationThread.Stub { //...省略其余方法 @Override 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赋值的一系列方法 //这里回调ActivityThread的sendMessage的方法 sendMessage(H.LAUNCH_ACTIVITY, r); } //...省略其余方法 } //继续跟进 private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } //继续跟进 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { Message msg = Message.obtain(); //...省略msg赋值过程 //调用ActivityThread的Handler开始启动消息队列 mH.sendMessage(msg); }
ActivityThread
的一个成员变量,mH的handleMessage()
会处理上一步发出的消息,现在看看它是怎么处理消息的private class H extends Handler { //...省略无关方法 public void handleMessage(Message msg) { switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); //取出消息中的ActivityClientRecord(客户端信息记录) final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); //调用此方法继续启动Activity handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; //... 省略其余case语句 } //... } //...省略无关方法 } //继续跟进 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { //... //根据参数r,初始化出一个Activity Activity a = performLaunchActivity(r, customIntent); if (a != null) { //... //如果Activity不为空,调用onResume()方法 handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); //... } else { // 如果Activity为空,也就是创建出错,交给服务端进行一些Activity结束的操作 try { ActivityManager.getService() .finishActivity(r.token, Activity.RESULT_CANCELED, null, Activity.DONT_FINISH_TASK_WITH_ACTIVITY); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } }
performLaunchActivity()
方法了private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { //... //1.获取要启动的Activity的ComponentName对象:里面包含了包名,类名相关的信息; ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } //.. //2.创建Activity的上下文环境:即创建了ContextImpl对象; ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //3.创建Activity的实例:调用Instrumentation$newActivity方法,并使用类加载器创建Activity对象; activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); //... } catch (Exception e) { //...省略抛异常 } try { //4.创建Application对象; Application app = r.packageInfo.makeApplication(false, mInstrumentation); //... if (activity != null) { //... //5.调用Activity$attach方法:初始化Activity类里的一些数据 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); //... //6.启动Activity:调用Instrumentation$callActivityOnCreate方法; activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } //... 省略别的生命周期的调用 } //.. } catch (SuperNotCalledException e) { //... } //... return activity; }
在performLaunchActivity
方法中,启动的过程大概会经过上述的六步调用,这时,Activity
就进入用户视线中了,上述六步中的后面五个步骤在流程图中都有体现。
我们这里再来分开看这五步是如何调用的
Activity
的上下文环境:即创建了ContextImpl
对象,也就是平时使用的context
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) { //... //进入ContextImpl的createActivityContext方法 ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); //... return appContext; } //进入ContextImpl的createActivityContext方法 static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration) { //... //此处调用构造方法,构造出context ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName, activityToken, null, 0, classLoader); //... return context; }
截止到createActivityContext
方法,context
创建完成
Activity
的实例:调用Instrumentation$newActivity
方法,并使用类加载器创建Activity
对象;public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//这里通过ClassLoader创建了Activity的实例
return (Activity)cl.loadClass(className).newInstance();
}
Application
对象;public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { //1. 不为空时候直接返回,显然,是个单例,所以一个应用只有一个Application if (mApplication != null) { return mApplication; } //... Application app = null; //... //2. 当为空时候,创建,这里和Activity类似,也是实用类加载器来创建的,有兴趣的可以继续查看 app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); //... //将app赋值到当前Application mApplication = app; //... //这里会调用Application的onCreate方法,接下来查看此方法 instrumentation.callApplicationOnCreate(app); //... return app; } //这里确实会调用Application的onCreate方法 public void callApplicationOnCreate(Application app) { app.onCreate(); }
到这里Application
的onCreate
方法也调用了。表明Application
创建成功
Activity$attach
方法:初始化Activity
类里的一些数据;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, Window window, ActivityConfigCallback activityConfigCallback) { //.. //创建了窗口对象PhoneWindow mWindow = new PhoneWindow(this, window, activityConfigCallback); //给窗口对象注册监听接口 mWindow.setWindowControllerCallback(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); //... //通过窗口Window创建WindowManagerImpl的实例 mWindow.setWindowManager( (WindowManager) context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); //... }
Activity
:调用Instrumentation$callActivityOnCreate
方法;public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); //此处调用Activity的方法,里面进行了onCreate操作 activity.performCreate(icicle, persistentState); postPerformCreate(activity); } //跟进performCreate方法 final void performCreate(Bundle icicle, PersistableBundle persistentState) { restoreHasCurrentPermissionRequest(icicle); //此处调用onCreate,整个流程分析终于结束 onCreate(icicle, persistentState); mActivityTransitionState.readState(icicle); performCreateCommon(); }
至此Activity
的启动了流程完成。
通过上面的调用,我们发现虽然调用的方法比较多,但整体流程还是比较清晰的。不过有的方法命名很迷,看着不太符合代码整洁之道,可能也是实在不好起名字了吧~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。