從源碼的角度描述Activity的啟動(dòng)過(guò)程

從源碼的角度描述Activity的啟動(dòng)過(guò)程

Activity作為Android四大組件之一赠橙,也是我們平時(shí)開(kāi)發(fā)中使用的最多的組件。作為四大組件中最為重要的老大摩渺,Activity究竟是如何啟動(dòng)的呢简烤?這篇文章從源碼的角度簡(jiǎn)單的為大家進(jìn)行解析。(PS:本文源碼基于7.0系統(tǒng))

一般啟動(dòng)Activity有兩種方法摇幻,這里就不再詳細(xì)說(shuō)這兩種方法了横侦,但是他們都是調(diào)用了同樣的一個(gè)邏輯startActivity()方法。所以我們分析Activity的啟動(dòng)流程就從這個(gè)方法開(kāi)始绰姻。請(qǐng)看下面startActivity()的源碼:

@Override

? ? public void startActivity(Intent intent) {

? ? ? ? this.startActivity(intent, null);

? ? }

? ? @Override

? ? public void startActivity(Intent intent, @Nullable Bundle options) {

? ? ? ? if (options != null) {

? ? ? ? ? ? startActivityForResult(intent, -1, options);

? ? ? ? } else {

? ? ? ? ? ? // Note we want to go through this call for compatibility with

? ? ? ? ? ? // applications that may have overridden the method.

? ? ? ? ? ? startActivityForResult(intent, -1);

? ? ? ? }

? ? }

可以看到startActivity()有多種重載方法枉侧,但是最終調(diào)用的還是startActivityForResult()方法。下面我們來(lái)看看源碼中startActivityForResult()的實(shí)現(xiàn):

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {

? ? ? ? startActivityForResult(intent, requestCode, null);

? ? }

? ? public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,

? ? ? ? ? ? @Nullable Bundle options) {

? ? ? ? //mParent是一個(gè)Activity對(duì)象狂芋,表示該Activity是否由父Activity啟動(dòng)

? ? ? ? if (mParent == null) {

? ? ? ? ? ? //這里會(huì)啟動(dòng)新的Activity榨馁,核心功能都在mMainThread.getApplicationThread()中完成?

? ? ? ? ? ? Instrumentation.ActivityResult ar =

? ? ? ? ? ? ? ? mInstrumentation.execStartActivity(

? ? ? ? ? ? ? ? ? ? this, mMainThread.getApplicationThread(), mToken, this,

? ? ? ? ? ? ? ? ? ? intent, requestCode, options);

? ? ? ? ? ? if (ar != null) {

? ? ? ? ? ? ? ? //發(fā)送結(jié)果,即onActivityResult會(huì)被調(diào)用?

? ? ? ? ? ? ? ? mMainThread.sendActivityResult(

? ? ? ? ? ? ? ? ? ? mToken, mEmbeddedID, requestCode, ar.getResultCode(),

? ? ? ? ? ? ? ? ? ? ar.getResultData());

? ? ? ? ? ? }

? ? ? ? ? ? //這里就是判斷requestCode的邏輯

? ? ? ? ? ? if (requestCode >= 0) {

? ? ? ? ? ? ? ? // If this start is requesting a result, we can avoid making

? ? ? ? ? ? ? ? // the activity visible until the result is received.? Setting

? ? ? ? ? ? ? ? // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the

? ? ? ? ? ? ? ? // activity hidden during this time, to avoid flickering.

? ? ? ? ? ? ? ? // This can only be done when a result is requested because

? ? ? ? ? ? ? ? // that guarantees we will get information back when the

? ? ? ? ? ? ? ? // activity is finished, no matter what happens to it.

? ? ? ? ? ? ? ? mStartedActivity = true;

? ? ? ? ? ? }

? ? ? ? ? ? cancelInputsAndStartExitTransition(options);

? ? ? ? ? ? // TODO Consider clearing/flushing other event sources and events for child windows.

? ? ? ? } else {

? ? ? ? ? ? if (options != null) {

? ? ? ? ? ? ? ? mParent.startActivityFromChild(this, intent, requestCode, options);

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? // Note we want to go through this method for compatibility with

? ? ? ? ? ? ? ? // existing applications that may have overridden it.

? ? ? ? ? ? ? ? mParent.startActivityFromChild(this, intent, requestCode);

? ? ? ? ? ? }

? ? ? ? }

? ? }

在startActivityForResult()方法中帜矾,首先會(huì)判斷該Activity是否由父Activity啟動(dòng)翼虫,即mParent,如果他是第一個(gè)Activity屡萤,就會(huì)調(diào)用Instrumentation的execStartActivity()方法,下面看看這個(gè)方法的源碼:

? public ActivityResult execStartActivity(

? ? ? ? ? ? Context who, IBinder contextThread, IBinder token, Activity target,

? ? ? ? ? ? Intent intent, int requestCode, Bundle options) {

? ? ? ? IApplicationThread whoThread = (IApplicationThread) contextThread;

? ? ? ? Uri referrer = target != null ? target.onProvideReferrer() : null;

? ? ? ? if (referrer != null) {

? ? ? ? ? ? intent.putExtra(Intent.EXTRA_REFERRER, referrer);

? ? ? ? }

? ? ? ? if (mActivityMonitors != null) {

? ? ? ? ? ? synchronized (mSync) {

? ? ? ? ? ? ? ? final int N = mActivityMonitors.size();

? ? ? ? ? ? ? ? for (int i=0; i

? ? ? ? ? ? ? ? ? ? final ActivityMonitor am = mActivityMonitors.get(i);

? ? ? ? ? ? ? ? ? ? if (am.match(who, null, intent)) {

? ? ? ? ? ? ? ? ? ? ? ? am.mHits++;

? ? ? ? ? ? ? ? ? ? ? ? if (am.isBlocking()) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? return requestCode >= 0 ? am.getResult() : null;

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? try {

? ? ? ? ? ? intent.migrateExtraStreamToClipData();

? ? ? ? ? ? intent.prepareToLeaveProcess(who);

? ? ? ? ? ? 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;

? ? }

由源碼可以看出這個(gè)方法的核心代碼是調(diào)用了ActivityManagerNative.getDefault().startActivity()珍剑,接著看看getDefault()的源碼

? static public IActivityManager getDefault() {

? ? ? ? return gDefault.get();

? ? }


? ? private static final Singleton gDefault = new Singleton() {

? ? ? ? protected IActivityManager create() {

? ? ? ? ? ? IBinder b = ServiceManager.getService("activity");

? ? ? ? ? ? if (false) {

? ? ? ? ? ? ? ? Log.v("ActivityManager", "default service binder = " + b);

? ? ? ? ? ? }

? ? ? ? ? ? IActivityManager am = asInterface(b);

? ? ? ? ? ? if (false) {

? ? ? ? ? ? ? ? Log.v("ActivityManager", "default service = " + am);

? ? ? ? ? ? }

? ? ? ? ? ? return am;

? ? ? ? }

? ? };

看上面的代碼,IActivityManager 調(diào)用了asInterface() 方法死陆,它的源碼:

? ? static public IActivityManager asInterface(IBinder obj) {

? ? ? ? if (obj == null) {

? ? ? ? ? ? return null;

? ? ? ? }

? ? ? ? IActivityManager in =

? ? ? ? ? ? (IActivityManager)obj.queryLocalInterface(descriptor);

? ? ? ? if (in != null) {

? ? ? ? ? ? return in;

? ? ? ? }

? ? ? ? return new ActivityManagerProxy(obj);

? ? }

public ActivityManagerProxy(IBinder remote)

? ? {

? ? ? ? mRemote = remote;

? ? }

? ? public IBinder asBinder()

? ? {

? ? ? ? return mRemote;

? ? }

? ? public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,

? ? ? ? ? ? String resolvedType, IBinder resultTo, String resultWho, int requestCode,

? ? ? ? ? ? int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {

? ? ? ? Parcel data = Parcel.obtain();

? ? ? ? Parcel reply = Parcel.obtain();

? ? ? ? data.writeInterfaceToken(IActivityManager.descriptor);

? ? ? ? data.writeStrongBinder(caller != null ? caller.asBinder() : null);

? ? ? ? data.writeString(callingPackage);

? ? ? ? intent.writeToParcel(data, 0);

? ? ? ? data.writeString(resolvedType);

? ? ? ? data.writeStrongBinder(resultTo);

? ? ? ? data.writeString(resultWho);

? ? ? ? data.writeInt(requestCode);

? ? ? ? data.writeInt(startFlags);

? ? ? ? if (profilerInfo != null) {

? ? ? ? ? ? data.writeInt(1);

? ? ? ? ? ? profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);

? ? ? ? } else {

? ? ? ? ? ? data.writeInt(0);

? ? ? ? }

? ? ? ? if (options != null) {

? ? ? ? ? ? data.writeInt(1);

? ? ? ? ? ? options.writeToParcel(data, 0);

? ? ? ? } else {

? ? ? ? ? ? data.writeInt(0);

? ? ? ? }

? ? ? ? mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

? ? ? ? reply.readException();

? ? ? ? int result = reply.readInt();

? ? ? ? reply.recycle();

? ? ? ? data.recycle();

? ? ? ? return result;

? ? }

可以看到asInterface返回了一個(gè)ActivityManagerProxy對(duì)象招拙,也就是說(shuō)ActivityManagerNative.getDefault()返回的就是一個(gè)ActivityManagerProxy對(duì)象,通過(guò)之前的BInder機(jī)制的文章我們可以知道Proxy是運(yùn)行在客戶端的,客戶端通過(guò)將參數(shù)寫入Proxy類别凤,接著Proxy就會(huì)通過(guò)Binder去遠(yuǎn)程調(diào)用服務(wù)端的具體方法饰序,因此,我們只是借用ActivityManagerProxy來(lái)調(diào)用ActivityManagerService的方法ActivityManagerService繼承自ActivityManagerNative规哪,而ActivityManagerNative繼承自Binder并實(shí)現(xiàn)了IActivityManager這個(gè)Binder接口求豫,因此ActivityManagerService也是一個(gè)Binder,并且是IActivityManager的具體實(shí)現(xiàn)由缆。

接著看看在AMS中啟動(dòng)Activity注祖,源碼如下:

? ? @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) {

? ? ? ? return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,

? ? ? ? ? ? ? ? resultWho, requestCode, startFlags, profilerInfo, bOptions,

? ? ? ? ? ? ? ? UserHandle.getCallingUserId());

? ? }

? ? @Override

? ? 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) {

? ? ? ? enforceNotIsolatedCaller("startActivity");

? ? ? ? userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),

? ? ? ? ? ? ? ? userId, false, ALLOW_FULL_ONLY, "startActivity", null);

? ? ? ? // TODO: Switch to user app stacks here.

? ? ? ? return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,

? ? ? ? ? ? ? ? resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,

? ? ? ? ? ? ? ? profilerInfo, null, null, bOptions, false, userId, null, null);

? ? }

在startActivity中直接調(diào)用了startActivityAsUser方法,而在startActivityAsUser中則是調(diào)用mStackSupervisor.startActivityMayWait方法均唉。

startActivityMayWait函數(shù)源碼較長(zhǎng),簡(jiǎn)單總結(jié)起來(lái)流程如下:?

startActivityMayWait()->startActivityLocked()->startActivityUncheckedLocked()->startSpecificActivityLocked()->startActivityLocked()->resumeTopActivitiesLocked()->resumeTopActivityLocked()肚菠。

經(jīng)過(guò)一系列的調(diào)用之后舔箭,最終來(lái)到了startPausingLocked方法,它會(huì)執(zhí)行Activity的onPause方法蚊逢,從而結(jié)束當(dāng)前的Activity层扶。

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,boolean dontWait) {

? ? ...

? ? if (prev.app != null && prev.app.thread != null) {

? ? ? ? if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);

? ? ? ? try {

? ? ? ? ? ? EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,

? ? ? ? ? ? ? ? ? ? prev.userId, System.identityHashCode(prev),

? ? ? ? ? ? ? ? ? ? prev.shortComponentName);

? ? ? ? ? ? mService.updateUsageStats(prev, false);

? ? ? ? ? ? prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,

? ? ? ? ? ? ? ? ? ? userLeaving, prev.configChangeFlags, dontWait);

? ? ? ? } catch (Exception e) {

? ? ? ? ? ? // Ignore exception, if process died other code will cleanup.

? ? ? ? ? ? Slog.w(TAG, "Exception thrown during pause", e);

? ? ? ? ? ? mPausingActivity = null;

? ? ? ? ? ? mLastPausedActivity = null;

? ? ? ? ? ? mLastNoHistoryActivity = null;

? ? ? ? }

? ? } else {

? ? ? ? mPausingActivity = null;

? ? ? ? mLastPausedActivity = null;

? ? ? ? mLastNoHistoryActivity = null;

? ? }

? ? ...

}

這段代碼非常重要,因?yàn)閍pp.thread的類型為IApplicationThread烙荷,它的具體實(shí)現(xiàn)是ActivityThread中的ApplicationThread類镜会,而ApplicationThread則是ActivityThread的一個(gè)內(nèi)部類,它繼承了IApplicationThread终抽,并且都是Binder對(duì)象戳表,所以說(shuō)Appcation是一個(gè)客戶端,而ActivityThread是一個(gè)服務(wù)端昼伴,到現(xiàn)在為止匾旭,Activity的調(diào)用來(lái)到了ActivityThread中。

在ActivityThread中pause掉當(dāng)前Activity圃郊,是調(diào)用了schedulePauseActivity來(lái)執(zhí)行pause操作:

public final void schedulePauseActivity(IBinder token, boolean finished,

? ? ? ? ? ? ? ? boolean userLeaving, int configChanges, boolean dontReport) {

? ? ? ? ? ? int seq = getLifecycleSeq();

? ? ? ? ? ? if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this

? ? ? ? ? ? ? ? ? ? + " operation received seq: " + seq);

? ? ? ? ? ? sendMessage(

? ? ? ? ? ? ? ? ? ? finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,

? ? ? ? ? ? ? ? ? ? token,

? ? ? ? ? ? ? ? ? ? (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),

? ? ? ? ? ? ? ? ? ? configChanges,

? ? ? ? ? ? ? ? ? ? seq);

? ? ? ? }

可以看到在schedulePauseActivity中則是通過(guò)handler來(lái)發(fā)送消息价涝,消息類型為PAUSE_ACTIVITY_FINISHING

? private void handlePauseActivity(IBinder token, boolean finished,

? ? ? ? ? ? boolean userLeaving, int configChanges, boolean dontReport, int seq) {

? ? ? ? ActivityClientRecord r = mActivities.get(token);

? ? ? ? if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);

? ? ? ? if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? if (r != null) {

? ? ? ? ? ? //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);

? ? ? ? ? ? if (userLeaving) {

? ? ? ? ? ? ? ? performUserLeavingActivity(r);

? ? ? ? ? ? }

? ? ? ? ? ? r.activity.mConfigChangeFlags |= configChanges;

? ? ? ? ? ? performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");

? ? ? ? ? ? // Make sure any pending writes are now committed.

? ? ? ? ? ? if (r.isPreHoneycomb()) {

? ? ? ? ? ? ? ? QueuedWork.waitToFinish();

? ? ? ? ? ? }

? ? ? ? ? ? // Tell the activity manager we have paused.

? ? ? ? ? ? if (!dontReport) {

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? ActivityManagerNative.getDefault().activityPaused(token);

? ? ? ? ? ? ? ? } catch (RemoteException ex) {

? ? ? ? ? ? ? ? ? ? throw ex.rethrowFromSystemServer();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? mSomeActivitiesChanged = true;

? ? ? ? }

? ? }

啟動(dòng)新的Activity,?在startSpecificActivityLocked方法中持舆,其實(shí)現(xiàn)細(xì)節(jié)則是和調(diào)用Activity的pause方法一樣色瘩,都是通過(guò)Handler機(jī)制,發(fā)送一個(gè)啟動(dòng)Activity的消息逸寓,接著處理該消息最后啟動(dòng)Activity居兆。其調(diào)用的是performLaunchActivity方法:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

? ? ? ? // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

? ? ? ? ActivityInfo aInfo = r.activityInfo;

? ? ? ? if (r.packageInfo == null) {

? ? ? ? ? ? r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,

? ? ? ? ? ? ? ? ? ? Context.CONTEXT_INCLUDE_CODE);

? ? ? ? }

? ? ? ? ComponentName component = r.intent.getComponent();

? ? ? ? if (component == null) {

? ? ? ? ? ? component = r.intent.resolveActivity(

? ? ? ? ? ? ? ? mInitialApplication.getPackageManager());

? ? ? ? ? ? r.intent.setComponent(component);

? ? ? ? }

? ? ? ? if (r.activityInfo.targetActivity != null) {

? ? ? ? ? ? component = new ComponentName(r.activityInfo.packageName,

? ? ? ? ? ? ? ? ? ? r.activityInfo.targetActivity);

? ? ? ? }

? ? ? ? Activity activity = null;

? ? ? ? try {

? ? ? ? ? ? java.lang.ClassLoader cl = r.packageInfo.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);

? ? ? ? ? ? }

? ? ? ? } catch (Exception e) {

? ? ? ? ? ? if (!mInstrumentation.onException(activity, e)) {

? ? ? ? ? ? ? ? throw new RuntimeException(

? ? ? ? ? ? ? ? ? ? "Unable to instantiate activity " + component

? ? ? ? ? ? ? ? ? ? + ": " + e.toString(), e);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? try {

? ? ? ? ? ? Application app = r.packageInfo.makeApplication(false, mInstrumentation);

? ? ? ? ? ? if (localLOGV) Slog.v(TAG, "Performing launch of " + r);

? ? ? ? ? ? if (localLOGV) Slog.v(

? ? ? ? ? ? ? ? ? ? TAG, r + ": app=" + app

? ? ? ? ? ? ? ? ? ? + ", appName=" + app.getPackageName()

? ? ? ? ? ? ? ? ? ? + ", pkg=" + r.packageInfo.getPackageName()

? ? ? ? ? ? ? ? ? ? + ", comp=" + r.intent.getComponent().toShortString()

? ? ? ? ? ? ? ? ? ? + ", dir=" + r.packageInfo.getAppDir());

? ? ? ? ? ? if (activity != null) {

? ? ? ? ? ? ? ? Context appContext = createBaseContextForActivity(r, activity);

? ? ? ? ? ? ? ? CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());

? ? ? ? ? ? ? ? Configuration config = new Configuration(mCompatConfiguration);

? ? ? ? ? ? ? ? if (r.overrideConfig != null) {

? ? ? ? ? ? ? ? ? ? config.updateFrom(r.overrideConfig);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "

? ? ? ? ? ? ? ? ? ? ? ? + r.activityInfo.name + " with config " + config);

? ? ? ? ? ? ? ? Window window = null;

? ? ? ? ? ? ? ? if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {

? ? ? ? ? ? ? ? ? ? window = r.mPendingRemoveWindow;

? ? ? ? ? ? ? ? ? ? r.mPendingRemoveWindow = null;

? ? ? ? ? ? ? ? ? ? r.mPendingRemoveWindowManager = null;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? 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);

? ? ? ? ? ? ? ? if (customIntent != null) {

? ? ? ? ? ? ? ? ? ? activity.mIntent = customIntent;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? r.lastNonConfigurationInstances = null;

? ? ? ? ? ? ? ? activity.mStartedActivity = false;

? ? ? ? ? ? ? ? int theme = r.activityInfo.getThemeResource();

? ? ? ? ? ? ? ? if (theme != 0) {

? ? ? ? ? ? ? ? ? ? activity.setTheme(theme);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? activity.mCalled = false;

? ? ? ? ? ? ? ? if (r.isPersistable()) {

? ? ? ? ? ? ? ? ? ? mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? mInstrumentation.callActivityOnCreate(activity, r.state);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (!activity.mCalled) {

? ? ? ? ? ? ? ? ? ? throw new SuperNotCalledException(

? ? ? ? ? ? ? ? ? ? ? ? "Activity " + r.intent.getComponent().toShortString() +

? ? ? ? ? ? ? ? ? ? ? ? " did not call through to super.onCreate()");

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? r.activity = activity;

? ? ? ? ? ? ? ? r.stopped = true;

? ? ? ? ? ? ? ? if (!r.activity.mFinished) {

? ? ? ? ? ? ? ? ? ? activity.performStart();

? ? ? ? ? ? ? ? ? ? r.stopped = false;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (!r.activity.mFinished) {

? ? ? ? ? ? ? ? ? ? if (r.isPersistable()) {

? ? ? ? ? ? ? ? ? ? ? ? if (r.state != null || r.persistentState != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r.persistentState);

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? } else if (r.state != null) {

? ? ? ? ? ? ? ? ? ? ? ? mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (!r.activity.mFinished) {

? ? ? ? ? ? ? ? ? ? activity.mCalled = false;

? ? ? ? ? ? ? ? ? ? if (r.isPersistable()) {

? ? ? ? ? ? ? ? ? ? ? ? mInstrumentation.callActivityOnPostCreate(activity, r.state,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r.persistentState);

? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? mInstrumentation.callActivityOnPostCreate(activity, r.state);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if (!activity.mCalled) {

? ? ? ? ? ? ? ? ? ? ? ? throw new SuperNotCalledException(

? ? ? ? ? ? ? ? ? ? ? ? ? ? "Activity " + r.intent.getComponent().toShortString() +

? ? ? ? ? ? ? ? ? ? ? ? ? ? " did not call through to super.onPostCreate()");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? r.paused = true;

? ? ? ? ? ? mActivities.put(r.token, r);

? ? ? ? } catch (SuperNotCalledException e) {

? ? ? ? ? ? throw e;

? ? ? ? } catch (Exception e) {

? ? ? ? ? ? if (!mInstrumentation.onException(activity, e)) {

? ? ? ? ? ? ? ? throw new RuntimeException(

? ? ? ? ? ? ? ? ? ? "Unable to start activity " + component

? ? ? ? ? ? ? ? ? ? + ": " + e.toString(), e);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return activity;

? ? }

可以看到最終的Activity對(duì)象終于創(chuàng)建出來(lái)了。

參考《Android開(kāi)發(fā)藝術(shù)探索》作者博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末席覆,一起剝皮案震驚了整個(gè)濱河市史辙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖聊倔,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晦毙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡耙蔑,警方通過(guò)查閱死者的電腦和手機(jī)见妒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)甸陌,“玉大人须揣,你說(shuō)我怎么就攤上這事∏恚” “怎么了耻卡?”我有些...
    開(kāi)封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)牲尺。 經(jīng)常有香客問(wèn)我卵酪,道長(zhǎng),這世上最難降的妖魔是什么谤碳? 我笑而不...
    開(kāi)封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任溃卡,我火速辦了婚禮,結(jié)果婚禮上蜒简,老公的妹妹穿的比我還像新娘瘸羡。我一直安慰自己,他們只是感情好搓茬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布犹赖。 她就那樣靜靜地躺著,像睡著了一般垮兑。 火紅的嫁衣襯著肌膚如雪冷尉。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天系枪,我揣著相機(jī)與錄音雀哨,去河邊找鬼。 笑死私爷,一個(gè)胖子當(dāng)著我的面吹牛雾棺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衬浑,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼捌浩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了工秩?” 一聲冷哼從身側(cè)響起尸饺,我...
    開(kāi)封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤进统,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后浪听,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體螟碎,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年迹栓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掉分。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡克伊,死狀恐怖酥郭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愿吹,我是刑警寧澤不从,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站犁跪,受9級(jí)特大地震影響消返,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耘拇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宇攻。 院中可真熱鬧惫叛,春花似錦、人聲如沸逞刷。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夸浅。三九已至仑最,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帆喇,已是汗流浹背警医。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坯钦,地道東北人预皇。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像婉刀,于是被迫代替她去往敵國(guó)和親吟温。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容