Activity啟動過程分析

通常我們在Activity中啟動一個另一個Activity,就是調用Activity的startActivity方法,這個最終會調用到Activity的startActivityForResult方法。那你有沒有想過Activity的啟動到底經歷了哪些過程,我們今天就來分析一下。

在具體分析之前,要先說明一下,Activity的啟動流程在細節挺繁瑣的,比如啟動另一個App的Activity或者啟動不同的launchMode的Activity,在細節上都會有不同。我們這次的源碼分析著重分析一下流程,為了簡單起見,就以分析一個Activity啟動app內部另一個standard模式的Activity為主。

Activity啟動另一個Activity之前,當前的Activity先要執行onPause,被啟動的Activity才會執行到onResume方法。這中間實際上是會執行4次IPC過程的:

當前Activity發起啟動另一個Activity的請求——>ActivityManagerService

ActivityManagerService——> 通知App暫停當前Activity

當前App告知已經暫停了當前的Activity——> ActivityManagerService

ActivityManagerService ——> 通知App啟動新的Activity

注:本次源碼分析采用Android7.0,不同版本的源碼在細節上會有不同,比如,在Android8.0上ActivityManagerService就改成了以AIDL的方式來寫,請不要太糾結API的不同。

注:本文Activity啟動過程源碼分析過程比較長,代碼較繁瑣,請做好心理準備。

Activity啟動涉及到的類

首先要簡單介紹一下Activity啟動過程涉及到的類,以便于更好的理解這個啟動過程。

ActivityThread:App啟動的入口

ApplicationThread:ActivityThread的內部類,繼承Binder,可以進程跨進程通信。

ApplicationThreadProxy:ApplicationThread的一個本地代理,其它的client端通過這個對象調用server端ApplicationThread中方法。

Instrumentation:負責發起Activity的啟動、并具體負責Activity的創建以及Activity生命周期的回調。一個應用進程只會有一個Instrumentation對象,App內的所有Activity都持有該對象的引用。

ActivityManagerService:簡稱AMS,是service端對象,負責管理系統中所有的Activity

ActivityManagerProxy:是ActivityManagerService的本地代理

ActivityStack:Activity在AMS的棧管理,用來記錄已經啟動的Activity的先后關系,狀態信息等。通過ActivityStack決定是否需要啟動新的進程。

ActivityRecord:ActivityStack的管理對象,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其他的管理信息。其實就是服務器端的Activity對象的映像。

TaskRecord:AMS抽象出來的一個“任務”的概念,是記錄ActivityRecord的棧,一個“Task”包含若干個ActivityRecord。AMS用TaskRecord確保Activity啟動和退出的順序。

介紹完這些,我們開始進入正題

Activity的啟動過程

Activity啟動最終會調用到startActivityForResult方法,我們只需要關注mParent == null中的邏輯即可。mParent代表的是ActivityGroup,其最開始是為了在一個界面中嵌入多個子Activity,在API13的時候就已經廢棄了,可以使用Fragment表示一個界面的多個區域。

# android.app.ActivitypublicvoidstartActivityForResult(@RequiresPermission Intent intent,intrequestCode,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Nullable Bundle options){if(mParent == null) {? ? ? ? Instrumentation.ActivityResult ar =? ? ? ? ? ? ? ? mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken,this,? ? ? ? ? ? ? ? ? ? ? ? intent, requestCode, options);if(ar != null) {? ? ? ? ? ? mMainThread.sendActivityResult(? ? ? ? ? ? ? ? ? ? mToken, mEmbeddedID, requestCode, ar.getResultCode(),? ? ? ? ? ? ? ? ? ? ar.getResultData());? ? ? ? }? ? ? ? ...? ? }else{? ? ? ? ...? ? }}

調用了Instrumentation的execStartActivity方法,在這里通過ActivityManagerNative.getDefault()方法獲取ActivityManagerService的一個本地代理對象ActivityManagerProxy,然后調用了其startActivity方法:

# android.app.InstrumentationpublicActivityResult execStartActivity(? ? ? ? Context who, IBinder contextThread, IBinder token, Activity target,? ? ? ? Intent intent, int requestCode, Bundle options) {? ? IApplicationThread whoThread = (IApplicationThread) contextThread;? ? ...try{? ? ? ...? ? ? ? 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) {thrownewRuntimeException("Failure from system", e);? ? }returnnull;}

我們看一下ActivityManagerNative,繼承了Binder并實現了IActivityManager接口,ActivityManagerService就是繼承了ActivityManagerNative。

publicabstractclassActivityManagerNativeextendsBinderimplementsIActivityManager

publicfinalclassActivityManagerServiceextendsActivityManagerNativeimplementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback

classActivityManagerProxyimplementsIActivityManager

ActivityManagerNative實際上獲取的就是其內部類ActivityManagerProxy對象。ActivityManagerProxy只是ActivityManagerService的本地代理對象,其startActivity方法會調用到AMS的startActivity方法。而且要注意,這個startActivity方法會把ApplicationThread對象傳遞到AMS所在進程,當然了AMS拿到的實際上是ApplicationThread的代理對象ApplicationThreadProxy,AMS就要通過這個代理對象與我們的App進程進行通信。

# android.app.ActivityManagerNativeprivatestaticfinalSingleton gDefault =newSingleton() {protectedIActivityManager 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);? ? ? ? }returnam;? ? }};staticpublicIActivityManager asInterface(IBinder obj) {if(obj ==null) {returnnull;? ? }? ? IActivityManager in =? ? ? ? ? ? (IActivityManager)obj.queryLocalInterface(descriptor);if(in !=null) {returnin;? ? }returnnewActivityManagerProxy(obj);}staticpublicIActivityManager getDefault() {returngDefault.get();}

注:在Android8.0,由于使用AIDL的方式來寫ActivityManagerService,ActivityManagerNative已經過期。

我們接著看一下AMS的startActivity方法:

# com.android.server.am.ActivityManagerServicepublicfinalintstartActivity(IApplicationThread caller, String callingPackage,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent intent, String resolvedType, IBinder resultTo, String resultWho,intrequestCode,intstartFlags, ProfilerInfo profilerInfo, Bundle bOptions){returnstartActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,? ? ? ? ? ? resultWho, requestCode, startFlags, profilerInfo, bOptions,? ? ? ? ? ? UserHandle.getCallingUserId());}

startActivity方法緊接著調用了其startActivityAsUser方法。

@OverridepublicfinalintstartActivityAsUser(IApplicationThread caller, String callingPackage,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent intent, String resolvedType, IBinder resultTo, String resultWho,intrequestCode,intstartFlags, ProfilerInfo profilerInfo, Bundle bOptions,intuserId){? ? enforceNotIsolatedCaller("startActivity");? ? userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),? ? ? ? ? ? userId,false, ALLOW_FULL_ONLY,"startActivity",null);//TODO:Switch to user app stacks here.returnmActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,? ? ? ? ? ? resolvedType,null,null, resultTo, resultWho, requestCode, startFlags,? ? ? ? ? ? profilerInfo,null,null, bOptions,false, userId,null,null);}

接著調用了ActivityStarter的startActivityMayWait方法,由于方法很長,我們只保留關鍵的流程部分:

# com.android.server.am.ActivityStarterfinalintstartActivityMayWait(IApplicationThread caller,intcallingUid,? ? ? ? String callingPackage, Intent intent, String resolvedType,? ? ? ? IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,? ? ? ? IBinder resultTo, String resultWho,intrequestCode,intstartFlags,? ? ? ? ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,? ? ? ? Bundle bOptions, boolean ignoreTargetSecurity,intuserId,? ? ? ? IActivityContainer iContainer, TaskRecord inTask){? ? ? ? ? ...intres = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,? ? ? ? ? ? ? ? aInfo, rInfo, voiceSession, voiceInteractor,? ? ? ? ? ? ? ? resultTo, resultWho, requestCode, callingPid,? ? ? ? ? ? ? ? callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,? ? ? ? ? ? ? ? options, ignoreTargetSecurity, componentSpecified, outRecord, container,? ? ? ? ? ? ? ? inTask);? ? ? ? ...? ? }}

ActivityStarter調用了自身的startActivityLocked方法,這又是一個很長的方法,保留關鍵的流程如下。

# com.android.server.am.ActivityStarterfinalintstartActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,? ? ? ? String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,? ? ? ? IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,? ? ? ? IBinder resultTo, String resultWho,intrequestCode,intcallingPid,intcallingUid,? ? ? ? String callingPackage,intrealCallingPid,intrealCallingUid,intstartFlags,? ? ? ? ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,? ? ? ? ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,? ? ? ? TaskRecord inTask){interr = ActivityManager.START_SUCCESS;? ? ...try{? ? ? ? mService.mWindowManager.deferSurfaceLayout();? ? ? ? err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true, options, inTask);? ? } finally {? ? ? ? mService.mWindowManager.continueSurfaceLayout();? ? }? ? postStartActivityUncheckedProcessing(r, err,stack.mStackId, mSourceRecord, mTargetStack);returnerr;}

ActivityStarter又調用了自身的startActivityUnchecked方法,

# com.android.server.am.ActivityStarterprivateintstartActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,? ? ? ? IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,intstartFlags, boolean doResume, ActivityOptions options, TaskRecord inTask){? ? ...if(mDoResume) {? ? ? ? ...if(!mTargetStack.isFocusable()? ? ? ? ? ? ...? ? ? ? }else{? ? ? ? ? ? mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,? ? ? ? ? ? ? ? ? ? mOptions);? ? ? ? }? ? }else{? ? ? ...? ? }? ? ...returnSTART_SUCCESS;}

在ActivityStarter中調用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法。

# com.android.server.am.ActivityStackSupervisorbooleanresumeFocusedStackTopActivityLocked(

? ? ? ? ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions){if(targetStack != null && isFocusedStack(targetStack)) {returntargetStack.resumeTopActivityUncheckedLocked(target, targetOptions);? ? }? ? ... }

在ActivityStackSupervisor的resumeFocusedStackTopActivityLocked中又調用了ActivityStack的resumeTopActivityUncheckedLocked方法。

# com.android.server.am.ActivityStackbooleanresumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options){? ...? ? boolean result =false;try{// Protect against recursion.mStackSupervisor.inResumeTopActivity =true;? ? ? ? ...? ? ? ? result = resumeTopActivityInnerLocked(prev, options);? ? } finally {? ? ? ? mStackSupervisor.inResumeTopActivity =false;? ? }returnresult;}

ActivityStack在resumeTopActivityUncheckedLocked又調用了其自身的resumeTopActivityInnerLocked方法。

# com.android.server.am.ActivityStackprivatebooleanresumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options){? ? ..// We need to start pausing the current activity so the top one can be resumed......if(mResumedActivity != null) {if(DEBUG_STATES) Slog.d(TAG_STATES,"resumeTopActivityLocked: Pausing "+ mResumedActivity);? ? ? ? pausing |= startPausingLocked(userLeaving,false, next, dontWaitForPause);? ? }? ? ...}

由于當前的Activity執行了onResume,所以mResumedActivity != null 條件滿足,就會調用startPausingLocked方法先暫停當前的Activity。注意:這個過程必然是一個IPC過程。我們看一下startPausingLocked方法。

# com.android.server.am.ActivityStackfinalboolean startPausingLocked(boolean userLeaving, boolean uiSleeping,? ? ? ? ActivityRecord resuming, boolean dontWait) {? ? ActivityRecord prev = mResumedActivity;? ? ...if(prev.app !=null&& prev.app.thread !=null) {if(DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Enqueueing pending pause: "+ prev);try{? ? ? ? ? ? ...? ? ? ? ? ? prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,? ? ? ? ? ? ? ? ? ? userLeaving, prev.configChangeFlags, dontWait);? ? ? ? }catch(Exceptione) {? ? ? ? ? ...? ? ? ? }? ? }else{? ? ? ...? ? }? ? ...}

prev.app.thread表示的是IApplicationThread對象,在這里就是指的發起啟動的Activity所在進程的ApplicationThread的本地代理ApplicationThreadProxy。調用它的schedulePauseActivity方法,很明顯是一次IPC過程,最終調用到server端,也就是發起啟動的Activity所在進程ApplicationThread的schedulePauseActivity方法。

# android.app.ActivityThread$$ApplicationThreadpublicfinalvoidschedulePauseActivity(IBinder token, boolean finished,? ? ? ? boolean userLeaving,intconfigChanges, boolean dontReport){intseq = 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);}

通過Hander的轉發,接著會調用到ActivityThread的handlePauseActivity方法。

# android.app.ActivityThreadprivatevoidhandlePauseActivity(IBinder token, boolean finished,? ? ? ? boolean userLeaving,intconfigChanges, boolean dontReport,intseq){? ? ActivityClientRecord r = mActivities.get(token);? ? ...if(r != null) {? ? ...? ? ? ? performPauseActivity(token, finished, r.isPreHoneycomb(),"handlePauseActivity");? ? ...// Tell the activity manager we have paused.if(!dontReport) {try{? ? ? ? ? ? ? ? ActivityManagerNative.getDefault().activityPaused(token);? ? ? ? ? ? }catch(RemoteException ex) {throwex.rethrowFromSystemServer();? ? ? ? ? ? }? ? ? ? }? ? ? ? mSomeActivitiesChanged =true;? ? }}

在ActivityThread的handlePauseActivity中,首先會調用performPauseActivity來暫停當前的Activity,經過層層調用,會調用到Intrumentation的callActivityOnPause方法,最終調用Activity的onPause方法,這一塊的流程比較簡單,在這里就不再詳細分析了,感興趣的可以自己研究下。

暫停之后,會調動ActivityManagerNative.getDefault().activityPaused(token),這個很明顯又是一次IPC過程,就是告訴AMS,已經暫停當前的Activity,可以啟動新的Activity 了。

我們來看一下AMS的的activityPaused方法:

# com.android.server.am.ActivityManagerService@OverridepublicfinalvoidactivityPaused(IBinder token){? ? finallongorigId = Binder.clearCallingIdentity();? ? synchronized(this) {? ? ? ? ActivityStackstack= ActivityRecord.getStackLocked(token);if(stack!= null) {stack.activityPausedLocked(token,false);? ? ? ? }? ? }? ? Binder.restoreCallingIdentity(origId);}

AMS中的activityPaused又調用了ActivityStack的activityPausedLocked方法。

# com.android.server.am.ActivityStackfinalvoid activityPausedLocked(IBinder token, boolean timeout) {? ? ...finalActivityRecord r = isInStackLocked(token);if(r !=null) {? ? ? ? mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);if(mPausingActivity == r) {if(DEBUG_STATES) Slog.v(TAG_STATES,"Moving to PAUSED: "+ r? ? ? ? ? ? ? ? ? ? + (timeout ?" (due to timeout)":" (pause complete)"));? ? ? ? ? ? completePauseLocked(true,null);return;? ? ? ? }else{? ? ? ? ? ...? ? ? ? }? ? }? ...}

在這個方法中又調用了ActivityStack自身的completePauseLocked方法,

# com.android.server.am.ActivityStackprivatevoidcompletePauseLocked(boolean resumeNext, ActivityRecord resuming){? ? ActivityRecord prev = mPausingActivity;if(resumeNext) {? ? ? ? final ActivityStack topStack = mStackSupervisor.getFocusedStack();if(!mService.isSleepingOrShuttingDownLocked()) {? ? ? ? ? ? mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);? ? ? ? }else{? ? ? ? ? ...? ? ? ? }? ? }? ? ...}

然后又調用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法,這視乎又重新調用了一遍,真復雜啊。

這個流程我們上面講過了,ActivityStackSupervisor會繼續調用ActivityStack的resumeTopActivityUncheckedLocked方法,然后ActivityStack又調用其resumeTopActivityInnerLocked方法,調來調去,又到這個方法里面了,上次在這里是執行了前一個Activity的onPause方法。這次會調用到ActivityStackSupersivor的startSpecificActivityLocked方法。

# com.android.server.am.ActivityStackprivateboolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {// We need to start pausing the current activity so the top one can be resumed...finalboolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) !=0;? ? boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);if(mResumedActivity !=null) {if(DEBUG_STATES) Slog.d(TAG_STATES,"resumeTopActivityLocked: Pausing "+ mResumedActivity);? ? ? ? pausing |= startPausingLocked(userLeaving,false, next, dontWaitForPause);? ? }? ? ...? ? ActivityStack lastStack = mStackSupervisor.getLastStack();if(next.app !=null&& next.app.thread !=null) {? ? ? ? ...? ? }else{? ? ? ? ...? ? ? ? mStackSupervisor.startSpecificActivityLocked(next,true,true);? ? }if(DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();returntrue;}

分析到這里,好像我們的就要開始啟動我們的目標Activity了,好激動有木有!

在ActivityStackSupersivor的startSpecificActivityLocked方法中會判斷Activity所在進程是否存在,如果不存在的話就要創建一個新的進程。在這里,我們是Activity啟動其App內部的另一個Activity,所以進程肯定是存在的,會走到realStartActivityLocked方法中。

# com.android.server.am.ActivityStackSupervisorvoidstartSpecificActivityLocked(ActivityRecord r,

? ? ? ? boolean andResume, boolean checkConfig){? ? ...if(app != null && app.thread != null) {try{? ? ...? ? ? ? ? ? realStartActivityLocked(r, app, andResume, checkConfig);return;? ? ? ? }catch(RemoteException e) {? ? ? ? ? ...? ? ? ? }? ? }? ? mService.startProcessLocked(r.processName, r.info.applicationInfo,true,0,"activity", r.intent.getComponent(),false,false,true);}

再來看一下ActivityStackSupersivor的realStartActivityLocked方法,這次似乎真的要啟動一個Activity了。

# com.android.server.am.ActivityStackSupervisorfinal booleanrealStartActivityLocked(ActivityRecord r, ProcessRecord app,

? ? ? ? boolean andResume, boolean checkConfig)throws RemoteException{? ? ...try{? ? ? ? app.thread.scheduleLaunchActivity(newIntent(r.intent), r.appToken,? ? ? ? ? ? ? ? System.identityHashCode(r), r.info,newConfiguration(mService.mConfiguration),newConfiguration(task.mOverrideConfig), r.compat, r.launchedFromPackage,? ? ? ? ? ? ? ? task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,? ? ? ? ? ? ? ? newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);? ? ? ...? ? }catch(RemoteException e) {? ? ? ...? ? }? ? ...returntrue;}

看了代碼,果然,調用了app.thread.scheduleLaunchActivity方法,app.thread我們前面講過,就是IApplicationThread對象,實際上就是ApplicationThreadProxy對象,經過IPC過程會調用到ApplicationThread的scheduleLaunchActivity方法,我們來看一下:

# android.app.ActivityThread$$ApplicationThread@OverridepublicfinalvoidscheduleLaunchActivity(Intent intent, IBinder token,intident,? ? ? ? ActivityInfo info, Configuration curConfig, Configuration overrideConfig,? ? ? ? CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,intprocState, Bundle state, PersistableBundle persistentState,? ? ? ? List pendingResults, List pendingNewIntents,? ? ? ? boolean notResumed, boolean isForward, ProfilerInfo profilerInfo){? ? ...? ? sendMessage(H.LAUNCH_ACTIVITY, r);}

通過Hander的轉發,接著會調用到ActivityThread的handlePauseActivity方法。

# android.app.ActivityThreadprivatevoidhandleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason){? ? ...? ? Activity a = performLaunchActivity(r, customIntent);if(a != null) {? ? ...? ? ? ? handleResumeActivity(r.token,false, r.isForward,? ? ? ? ? ? ? ? !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);? ? ? ...? ? }else{? ? ? ...? ? }}

handlePauseActivity內部調用performLaunchActivity方法:

# android.app.ActivityThreadprivateActivity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {? ? ...? ? Activity activity =null;try{? ? ? ? java.lang.ClassLoader cl = r.packageInfo.getClassLoader();? ? ? ? activity = mInstrumentation.newActivity(? ? ? ? ? ? ? ? cl, component.getClassName(), r.intent);? ? ? ? ...? ? }catch(Exceptione) {? ? ? ...? ? }try{? ? ? ? Application app = r.packageInfo.makeApplication(false, mInstrumentation);? ? ? ? ...if(activity !=null) {? ? ? ? ? ? Context appContext = createBaseContextForActivity(r, 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);? ? ? ? ? ? ...? ? ? ? ? ? activity.mCalled =false;if(r.isPersistable()) {? ? ? ? ? ? ? ? mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);? ? ? ? ? ? }else{? ? ? ? ? ? ? ? mInstrumentation.callActivityOnCreate(activity, r.state);? ? ? ? ? ? }? ? ? ? ? ...? ? ? ? ? ? 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);? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }elseif(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) {thrownewSuperNotCalledException("Activity "+ r.intent.getComponent().toShortString() +" did not call through to super.onPostCreate()");? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? ? ? r.paused =true;? ? ? ? mActivities.put(r.token, r);? ? }catch(SuperNotCalledException e) {throwe;? ? }catch(Exceptione) {? ? ? ...? ? }returnactivity;}

在performLaunchActivity內部,創建了Activity對象,并調用了activity的attach方法,在這個方法中綁定一些屬性,并且創建了Activity所屬的Window對象。接著Instrumentation會調用callActivityOnCreate、callActivityOnRestoreInstanceState、callActivityOnPostCreate等來完成Activity生命周期的回調。不過有一點很有意思,在這個方法中Activity自己調用了其performStart方法,但這個方法內部又調用了Instrumentation的callActivityOnStart方法,進而又調用了Activity的onStart方法。繞過來繞過去,總之,Activity生命周期方法的調用均是通過Instrumentation來控制的。

至此,Activity的啟動過程算是分析完了,太費腦筋了,需要來一瓶營養快線補補身體。流程太多,不好記,但是有句話說的好 "一圖勝千言",下面我們來看一下Activity啟動的一個時序圖。

Activity啟動過程.png

總結

源碼分析過程是比較繞,比較燒腦的過程,不要太糾結去API的調用,盡量側重流程。分析源碼,最好帶著問題去分析,不要為了分析而分析,盡量在分析過程中尋找自己想要的答案。比如:

Activity對象是怎么創建的?

Window對象是什么時候創建的?

LayoutInflater什么時候創建的?

為什么在Activity中的布局中或者Fragment的中View獲取的Context都是其所在的Activity對象?

為什么自定義View一定要有兩個參數的構造函數?

Activity的生命周期方法是被誰回調的?

Application是什么時候創建的?

ClassLoader對象是什么時候創建的?

子線程可以啟動Activity、Service嗎?

下拉通知欄,會影響Activity生命周期嗎?

筆者初入Android開發沒多久的時候,有次面試,面試官問我在子線程中啟動Activity可以嗎?我回答可以,因為我試過,但是問我為什么我卻不知道。如果那時候看了Activity啟動過程的源碼,看了Binder機制的話,應該很容易的就回答出來了。

參考

Android Launcher 啟動 Activity 的工作過程

【凱子哥帶你學Framework】Activity啟動過程全解析

Android進階——Android四大組件啟動機制之Activity啟動過程

作者:sososeen09

鏈接:http://www.lxweimin.com/p/13b07beacb1f

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容