通常我們?cè)贏ctivity中啟動(dòng)一個(gè)另一個(gè)Activity挽荡,就是調(diào)用Activity的startActivity方法逗嫡,這個(gè)最終會(huì)調(diào)用到Activity的startActivityForResult方法。那你有沒有想過Activity的啟動(dòng)到底經(jīng)歷了哪些過程抹锄,我們今天就來分析一下。
在具體分析之前吻育,要先說明一下币狠,Activity的啟動(dòng)流程在細(xì)節(jié)挺繁瑣的,比如啟動(dòng)另一個(gè)App的Activity或者啟動(dòng)不同的launchMode的Activity漩绵,在細(xì)節(jié)上都會(huì)有不同轰坊。我們這次的源碼分析著重分析一下流程粟害,為了簡(jiǎn)單起見,就以分析一個(gè)Activity啟動(dòng)app內(nèi)部另一個(gè)standard模式的Activity為主。
Activity啟動(dòng)另一個(gè)Activity之前,當(dāng)前的Activity先要執(zhí)行onPause聚蝶,被啟動(dòng)的Activity才會(huì)執(zhí)行到onResume方法桩卵。這中間實(shí)際上是會(huì)執(zhí)行4次IPC過程的:
當(dāng)前Activity發(fā)起啟動(dòng)另一個(gè)Activity的請(qǐng)求——>ActivityManagerService
ActivityManagerService——> 通知App暫停當(dāng)前Activity
當(dāng)前App告知已經(jīng)暫停了當(dāng)前的Activity——> ActivityManagerService
ActivityManagerService ——> 通知App啟動(dòng)新的Activity
注:本次源碼分析采用Android7.0,不同版本的源碼在細(xì)節(jié)上會(huì)有不同,比如,在Android8.0上ActivityManagerService就改成了以AIDL的方式來寫牵啦,請(qǐng)不要太糾結(jié)API的不同。
注:本文Activity啟動(dòng)過程源碼分析過程比較長(zhǎng),代碼較繁瑣,請(qǐng)做好心理準(zhǔn)備。
Activity啟動(dòng)涉及到的類
首先要簡(jiǎn)單介紹一下Activity啟動(dòng)過程涉及到的類经伙,以便于更好的理解這個(gè)啟動(dòng)過程。
ActivityThread:App啟動(dòng)的入口
ApplicationThread:ActivityThread的內(nèi)部類,繼承Binder茶宵,可以進(jìn)程跨進(jìn)程通信危纫。
ApplicationThreadProxy:ApplicationThread的一個(gè)本地代理,其它的client端通過這個(gè)對(duì)象調(diào)用server端ApplicationThread中方法乌庶。
Instrumentation:負(fù)責(zé)發(fā)起Activity的啟動(dòng)种蝶、并具體負(fù)責(zé)Activity的創(chuàng)建以及Activity生命周期的回調(diào)。一個(gè)應(yīng)用進(jìn)程只會(huì)有一個(gè)Instrumentation對(duì)象瞒大,App內(nèi)的所有Activity都持有該對(duì)象的引用螃征。
ActivityManagerService:簡(jiǎn)稱AMS,是service端對(duì)象透敌,負(fù)責(zé)管理系統(tǒng)中所有的Activity
ActivityManagerProxy:是ActivityManagerService的本地代理
ActivityStack:Activity在AMS的棧管理盯滚,用來記錄已經(jīng)啟動(dòng)的Activity的先后關(guān)系,狀態(tài)信息等酗电。通過ActivityStack決定是否需要啟動(dòng)新的進(jìn)程魄藕。
ActivityRecord:ActivityStack的管理對(duì)象,每個(gè)Activity在AMS對(duì)應(yīng)一個(gè)ActivityRecord撵术,來記錄Activity的狀態(tài)以及其他的管理信息背率。其實(shí)就是服務(wù)器端的Activity對(duì)象的映像。
TaskRecord:AMS抽象出來的一個(gè)“任務(wù)”的概念,是記錄ActivityRecord的棧寝姿,一個(gè)“Task”包含若干個(gè)ActivityRecord交排。AMS用TaskRecord確保Activity啟動(dòng)和退出的順序。
介紹完這些饵筑,我們開始進(jìn)入正題
Activity的啟動(dòng)過程
Activity啟動(dòng)最終會(huì)調(diào)用到startActivityForResult方法埃篓,我們只需要關(guān)注mParent == null中的邏輯即可。mParent代表的是ActivityGroup翻翩,其最開始是為了在一個(gè)界面中嵌入多個(gè)子Activity都许,在API13的時(shí)候就已經(jīng)廢棄了,可以使用Fragment表示一個(gè)界面的多個(gè)區(qū)域嫂冻。
# 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{? ? ? ? ...? ? }}
調(diào)用了Instrumentation的execStartActivity方法胶征,在這里通過ActivityManagerNative.getDefault()方法獲取ActivityManagerService的一個(gè)本地代理對(duì)象ActivityManagerProxy,然后調(diào)用了其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并實(shí)現(xiàn)了IActivityManager接口睛低,ActivityManagerService就是繼承了ActivityManagerNative。
publicabstractclassActivityManagerNativeextendsBinderimplementsIActivityManager
publicfinalclassActivityManagerServiceextendsActivityManagerNativeimplementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback
classActivityManagerProxyimplementsIActivityManager
ActivityManagerNative實(shí)際上獲取的就是其內(nèi)部類ActivityManagerProxy對(duì)象服傍。ActivityManagerProxy只是ActivityManagerService的本地代理對(duì)象钱雷,其startActivity方法會(huì)調(diào)用到AMS的startActivity方法。而且要注意吹零,這個(gè)startActivity方法會(huì)把ApplicationThread對(duì)象傳遞到AMS所在進(jìn)程罩抗,當(dāng)然了AMS拿到的實(shí)際上是ApplicationThread的代理對(duì)象ApplicationThreadProxy,AMS就要通過這個(gè)代理對(duì)象與我們的App進(jìn)程進(jìn)行通信灿椅。
# 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已經(jīng)過期茫蛹。
我們接著看一下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方法緊接著調(diào)用了其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);}
接著調(diào)用了ActivityStarter的startActivityMayWait方法,由于方法很長(zhǎng)婴洼,我們只保留關(guān)鍵的流程部分:
# 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調(diào)用了自身的startActivityLocked方法骨坑,這又是一個(gè)很長(zhǎng)的方法,保留關(guān)鍵的流程如下柬采。
# 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又調(diào)用了自身的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中調(diào)用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法。
# com.android.server.am.ActivityStackSupervisorbooleanresumeFocusedStackTopActivityLocked(
? ? ? ? ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions){if(targetStack != null && isFocusedStack(targetStack)) {returntargetStack.resumeTopActivityUncheckedLocked(target, targetOptions);? ? }? ? ... }
在ActivityStackSupervisor的resumeFocusedStackTopActivityLocked中又調(diào)用了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又調(diào)用了其自身的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);? ? }? ? ...}
由于當(dāng)前的Activity執(zhí)行了onResume,所以mResumedActivity != null 條件滿足杀迹,就會(huì)調(diào)用startPausingLocked方法先暫停當(dāng)前的Activity亡脸。注意:這個(gè)過程必然是一個(gè)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對(duì)象浅碾,在這里就是指的發(fā)起啟動(dòng)的Activity所在進(jìn)程的ApplicationThread的本地代理ApplicationThreadProxy大州。調(diào)用它的schedulePauseActivity方法,很明顯是一次IPC過程垂谢,最終調(diào)用到server端厦画,也就是發(fā)起啟動(dòng)的Activity所在進(jìn)程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的轉(zhuǎn)發(fā)滥朱,接著會(huì)調(diào)用到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中,首先會(huì)調(diào)用performPauseActivity來暫停當(dāng)前的Activity徙邻,經(jīng)過層層調(diào)用排嫌,會(huì)調(diào)用到Intrumentation的callActivityOnPause方法,最終調(diào)用Activity的onPause方法缰犁,這一塊的流程比較簡(jiǎn)單淳地,在這里就不再詳細(xì)分析了,感興趣的可以自己研究下帅容。
暫停之后颇象,會(huì)調(diào)動(dòng)ActivityManagerNative.getDefault().activityPaused(token),這個(gè)很明顯又是一次IPC過程并徘,就是告訴AMS遣钳,已經(jīng)暫停當(dāng)前的Activity,可以啟動(dòng)新的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又調(diào)用了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{? ? ? ? ? ...? ? ? ? }? ? }? ...}
在這個(gè)方法中又調(diào)用了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{? ? ? ? ? ...? ? ? ? }? ? }? ? ...}
然后又調(diào)用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法路幸,這視乎又重新調(diào)用了一遍,真復(fù)雜啊付翁。
這個(gè)流程我們上面講過了简肴,ActivityStackSupervisor會(huì)繼續(xù)調(diào)用ActivityStack的resumeTopActivityUncheckedLocked方法,然后ActivityStack又調(diào)用其resumeTopActivityInnerLocked方法百侧,調(diào)來調(diào)去砰识,又到這個(gè)方法里面了,上次在這里是執(zhí)行了前一個(gè)Activity的onPause方法佣渴。這次會(huì)調(diào)用到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;}
分析到這里,好像我們的就要開始啟動(dòng)我們的目標(biāo)Activity了辛润,好激動(dòng)有木有膨处!
在ActivityStackSupersivor的startSpecificActivityLocked方法中會(huì)判斷Activity所在進(jìn)程是否存在,如果不存在的話就要?jiǎng)?chuàng)建一個(gè)新的進(jìn)程。在這里真椿,我們是Activity啟動(dòng)其App內(nèi)部的另一個(gè)Activity鹃答,所以進(jìn)程肯定是存在的,會(huì)走到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方法测摔,這次似乎真的要啟動(dòng)一個(gè)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;}
看了代碼解恰,果然锋八,調(diào)用了app.thread.scheduleLaunchActivity方法,app.thread我們前面講過护盈,就是IApplicationThread對(duì)象挟纱,實(shí)際上就是ApplicationThreadProxy對(duì)象,經(jīng)過IPC過程會(huì)調(diào)用到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的轉(zhuǎn)發(fā)樊销,接著會(huì)調(diào)用到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內(nèi)部調(diào)用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內(nèi)部脏款,創(chuàng)建了Activity對(duì)象围苫,并調(diào)用了activity的attach方法,在這個(gè)方法中綁定一些屬性撤师,并且創(chuàng)建了Activity所屬的Window對(duì)象剂府。接著Instrumentation會(huì)調(diào)用callActivityOnCreate、callActivityOnRestoreInstanceState剃盾、callActivityOnPostCreate等來完成Activity生命周期的回調(diào)腺占。不過有一點(diǎn)很有意思,在這個(gè)方法中Activity自己調(diào)用了其performStart方法痒谴,但這個(gè)方法內(nèi)部又調(diào)用了Instrumentation的callActivityOnStart方法衰伯,進(jìn)而又調(diào)用了Activity的onStart方法。繞過來繞過去积蔚,總之意鲸,Activity生命周期方法的調(diào)用均是通過Instrumentation來控制的。
至此尽爆,Activity的啟動(dòng)過程算是分析完了怎顾,太費(fèi)腦筋了,需要來一瓶營(yíng)養(yǎng)快線補(bǔ)補(bǔ)身體漱贱。流程太多槐雾,不好記,但是有句話說的好 "一圖勝千言"幅狮,下面我們來看一下Activity啟動(dòng)的一個(gè)時(shí)序圖募强。
Activity啟動(dòng)過程.png
總結(jié)
源碼分析過程是比較繞株灸,比較燒腦的過程,不要太糾結(jié)去API的調(diào)用钻注,盡量側(cè)重流程蚂且。分析源碼,最好帶著問題去分析幅恋,不要為了分析而分析杏死,盡量在分析過程中尋找自己想要的答案。比如:
Activity對(duì)象是怎么創(chuàng)建的捆交?
Window對(duì)象是什么時(shí)候創(chuàng)建的淑翼?
LayoutInflater什么時(shí)候創(chuàng)建的?
為什么在Activity中的布局中或者Fragment的中View獲取的Context都是其所在的Activity對(duì)象品追?
為什么自定義View一定要有兩個(gè)參數(shù)的構(gòu)造函數(shù)玄括?
Activity的生命周期方法是被誰回調(diào)的?
Application是什么時(shí)候創(chuàng)建的肉瓦?
ClassLoader對(duì)象是什么時(shí)候創(chuàng)建的遭京?
子線程可以啟動(dòng)Activity、Service嗎泞莉?
下拉通知欄哪雕,會(huì)影響Activity生命周期嗎?
筆者初入Android開發(fā)沒多久的時(shí)候鲫趁,有次面試斯嚎,面試官問我在子線程中啟動(dòng)Activity可以嗎?我回答可以挨厚,因?yàn)槲以囘^堡僻,但是問我為什么我卻不知道。如果那時(shí)候看了Activity啟動(dòng)過程的源碼疫剃,看了Binder機(jī)制的話钉疫,應(yīng)該很容易的就回答出來了。
參考
Android Launcher 啟動(dòng) Activity 的工作過程
【凱子哥帶你學(xué)Framework】Activity啟動(dòng)過程全解析
Android進(jìn)階——Android四大組件啟動(dòng)機(jī)制之Activity啟動(dòng)過程
作者:sososeen09
鏈接:http://www.reibang.com/p/13b07beacb1f
來源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有巢价,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處牲阁。