//packages/apps/Launcher3/src/com/android/launcher3/Launcher.javapublicbooleanstartActivitySafely(Viewv,Intentintent,ItemInfoitem,@NullableStringsourceContainer){if(!hasBeenResumed()){// Workaround an issue where the WM launch animation is clobbered when finishing the// recents animation into launcher. Defer launching the activity until Launcher is// next resumed.addOnResumeCallback(()->startActivitySafely(v,intent,item,sourceContainer));UiFactory.clearSwipeSharedState(true/* finishAnimation */);returntrue;}//这里调用的是BaseDraggingActivity的startActivitySafelybooleansuccess=super.startActivitySafely(v,intent,item,sourceContainer);if(success&&vinstanceofBubbleTextView){// This is set to the view that launched the activity that navigated the user away// from launcher. Since there is no callback for when the activity has finished// launching, enable the press state and keep this reference to reset the press// state when we return to launcher.BubbleTextViewbtv=(BubbleTextView)v;btv.setStayPressed(true);addOnResumeCallback(btv);}returnsuccess;}
//packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.javapublicbooleanstartActivitySafely(Viewv,Intentintent,@NullableItemInfoitem,@NullableStringsourceContainer){if(mIsSafeModeEnabled&&!PackageManagerHelper.isSystemApp(this,intent)){Toast.makeText(this,R.string.safemode_shortcut_error,Toast.LENGTH_SHORT).show();returnfalse;}BundleoptsBundle=(v!=null)?getActivityLaunchOptionsAsBundle(v):null;UserHandleuser=item==null?null:item.user;// Prepare intent//①intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if(v!=null){intent.setSourceBounds(getViewBounds(v));}try{booleanisShortcut=(iteminstanceofWorkspaceItemInfo)&&(item.itemType==Favorites.ITEM_TYPE_SHORTCUT||item.itemType==Favorites.ITEM_TYPE_DEEP_SHORTCUT)&&!((WorkspaceItemInfo)item).isPromise();if(isShortcut){// Shortcuts need some special checks due to legacy reasons.startShortcutIntentSafely(intent,optsBundle,item,sourceContainer);}elseif(user==null||user.equals(Process.myUserHandle())){// Could be launching some bookkeeping activity//调用Activity的startActivity方法startActivity(intent,optsBundle);AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),Process.myUserHandle(),sourceContainer);}else{LauncherAppsCompat.getInstance(this).startActivityForProfile(intent.getComponent(),user,intent.getSourceBounds(),optsBundle);AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),user,sourceContainer);}getUserEventDispatcher().logAppLaunch(v,intent);getStatsLogManager().logAppLaunch(v,intent);returntrue;}catch(NullPointerException|ActivityNotFoundException|SecurityExceptione){Toast.makeText(this,R.string.activity_not_found,Toast.LENGTH_SHORT).show();Log.e(TAG,"Unable to launch. tag="+item+" intent="+intent,e);}returnfalse;}
@OverridepublicvoidstartActivity(Intentintent,@NullableBundleoptions){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);}}
//frameworks/base/core/java/android/app/Instrumentation.javapublicActivityResultexecStartActivity(Contextwho,IBindercontextThread,IBindertoken,Activitytarget,Intentintent,intrequestCode,Bundleoptions){try{intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);//远程调用ATMS的startActivity方法intresult=ActivityTaskManager.getService().startActivity(whoThread,who.getBasePackageName(),intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token,target!=null?target.mEmbeddedID:null,requestCode,0,null,options);checkStartActivityResult(result,intent);//校验返回结果}catch(RemoteExceptione){thrownewRuntimeException("Failure from system",e);}returnnull;}
publicstaticvoidcheckStartActivityResult(intres,Objectintent){if(!ActivityManager.isStartResultFatalError(res)){return;}switch(res){caseActivityManager.START_INTENT_NOT_RESOLVED:caseActivityManager.START_CLASS_NOT_FOUND:if(intentinstanceofIntent&&((Intent)intent).getComponent()!=null)thrownewActivityNotFoundException("Unable to find explicit activity class "+((Intent)intent).getComponent().toShortString()+"; have you declared this activity in your AndroidManifest.xml?");thrownewActivityNotFoundException("No Activity found to handle "+intent);caseActivityManager.START_PERMISSION_DENIED:thrownewSecurityException("Not allowed to start activity "+intent);caseActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:thrownewAndroidRuntimeException("FORWARD_RESULT_FLAG used while also requesting a result");caseActivityManager.START_NOT_ACTIVITY:thrownewIllegalArgumentException("PendingIntent is not an activity");caseActivityManager.START_NOT_VOICE_COMPATIBLE:thrownewSecurityException("Starting under voice control not allowed for: "+intent);caseActivityManager.START_VOICE_NOT_ACTIVE_SESSION:thrownewIllegalStateException("Session calling startVoiceActivity does not match active session");caseActivityManager.START_VOICE_HIDDEN_SESSION:thrownewIllegalStateException("Cannot start voice activity on a hidden session");caseActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:thrownewIllegalStateException("Session calling startAssistantActivity does not match active session");caseActivityManager.START_ASSISTANT_HIDDEN_SESSION:thrownewIllegalStateException("Cannot start assistant activity on a hidden session");caseActivityManager.START_CANCELED:thrownewAndroidRuntimeException("Activity could not be started for "+intent);default:thrownewAndroidRuntimeException("Unknown error code "+res+" when starting "+intent);}}
intstartActivityAsUser(IApplicationThreadcaller,StringcallingPackage,Intentintent,StringresolvedType,IBinderresultTo,StringresultWho,intrequestCode,intstartFlags,ProfilerInfoprofilerInfo,BundlebOptions,intuserId,booleanvalidateIncomingUser){//①判断调用者进程是否被隔离enforceNotIsolatedCaller("startActivityAsUser");//②检查使用者权限userId=getActivityStartController().checkTargetUser(userId,validateIncomingUser,Binder.getCallingPid(),Binder.getCallingUid(),"startActivityAsUser");// TODO: Switch to user app stacks here.//先获取ActivityStartController对象。然后调用obtainStarter方法获取ActivityStarter对象//frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java// returngetActivityStartController().obtainStarter(intent,"startActivityAsUser").setCaller(caller).setCallingPackage(callingPackage).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setMayWait(userId)//设置MayWait为true.execute();}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaintexecute(){try{// TODO(b/64750076): Look into passing request directly to these methods to allow// for transactional diffs and preprocessing.if(mRequest.mayWait){returnstartActivityMayWait(mRequest.caller,mRequest.callingUid,mRequest.callingPackage,mRequest.realCallingPid,mRequest.realCallingUid,mRequest.intent,mRequest.resolvedType,mRequest.voiceSession,mRequest.voiceInteractor,mRequest.resultTo,mRequest.resultWho,mRequest.requestCode,mRequest.startFlags,mRequest.profilerInfo,mRequest.waitResult,mRequest.globalConfig,mRequest.activityOptions,mRequest.ignoreTargetSecurity,mRequest.userId,mRequest.inTask,mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup,mRequest.originatingPendingIntent,mRequest.allowBackgroundActivityStart);}else{//...}}finally{onExecutionComplete();}}
privateintstartActivityMayWait(IApplicationThreadcaller,intcallingUid,StringcallingPackage,intrequestRealCallingPid,intrequestRealCallingUid,Intentintent,StringresolvedType,IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,IBinderresultTo,StringresultWho,intrequestCode,intstartFlags,ProfilerInfoprofilerInfo,WaitResultoutResult,ConfigurationglobalConfig,SafeActivityOptionsoptions,booleanignoreTargetSecurity,intuserId,TaskRecordinTask,Stringreason,booleanallowPendingRemoteAnimationRegistryLookup,PendingIntentRecordoriginatingPendingIntent,booleanallowBackgroundActivityStart){//解析IntentResolveInforInfo=mSupervisor.resolveIntent(intent,resolvedType,userId,0/* matchFlags */,computeResolveFilterUid(callingUid,realCallingUid,mRequest.filterCallingUid));//...// Collect information about the target of the Intent.ActivityInfoaInfo=mSupervisor.resolveActivity(intent,rInfo,startFlags,profilerInfo);synchronized(mService.mGlobalLock){//调用startActivityintres=startActivity(caller,intent,ephemeralIntent,resolvedType,aInfo,rInfo,voiceSession,voiceInteractor,resultTo,resultWho,requestCode,callingPid,callingUid,callingPackage,realCallingPid,realCallingUid,startFlags,options,ignoreTargetSecurity,componentSpecified,outRecord,inTask,reason,allowPendingRemoteAnimationRegistryLookup,originatingPendingIntent,allowBackgroundActivityStart);//...//...returnres;}}
privateintstartActivity(IApplicationThreadcaller,Intentintent,IntentephemeralIntent,StringresolvedType,ActivityInfoaInfo,ResolveInforInfo,IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,IBinderresultTo,StringresultWho,intrequestCode,intcallingPid,intcallingUid,StringcallingPackage,intrealCallingPid,intrealCallingUid,intstartFlags,SafeActivityOptionsoptions,booleanignoreTargetSecurity,booleancomponentSpecified,ActivityRecord[]outActivity,TaskRecordinTask,booleanallowPendingRemoteAnimationRegistryLookup,PendingIntentRecordoriginatingPendingIntent,booleanallowBackgroundActivityStart){mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);interr=ActivityManager.START_SUCCESS;// Pull the optional Ephemeral Installer-only bundle out of the options early.finalBundleverificationBundle=options!=null?options.popAppVerificationBundle():null;WindowProcessControllercallerApp=null;if(caller!=null){//① 得到Launcher进程callerApp=mService.getProcessController(caller);//②if(callerApp!=null){//获取Launcher进程的pid和uidcallingPid=callerApp.getPid();callingUid=callerApp.mInfo.uid;}else{Slog.w(TAG,"Unable to find app for caller "+caller+" (pid="+callingPid+") when starting: "+intent.toString());err=ActivityManager.START_PERMISSION_DENIED;}}//...//创建即将要启动的Activity的描述类ActivityRecordActivityRecordr=newActivityRecord(mService,callerApp,callingPid,callingUid,callingPackage,intent,resolvedType,aInfo,mService.getGlobalConfiguration(),resultRecord,resultWho,requestCode,componentSpecified,voiceSession!=null,mSupervisor,checkedOptions,sourceRecord);if(outActivity!=null){outActivity[0]=r;//③}//...//④ 调用重载方法finalintres=startActivity(r,sourceRecord,voiceSession,voiceInteractor,startFlags,true/* doResume */,checkedOptions,inTask,outActivity,restrictedBgActivity);mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res,outActivity[0]);returnres;}
privateintstartActivityUnchecked(finalActivityRecordr,ActivityRecordsourceRecord,IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,intstartFlags,booleandoResume,ActivityOptionsoptions,TaskRecordinTask,ActivityRecord[]outActivity,booleanrestrictedBgActivity){//...//①if(mStartActivity.resultTo==null&&mInTask==null&&!mAddingToTask&&(mLaunchFlags&FLAG_ACTIVITY_NEW_TASK)!=0){newTask=true;//②创建新的TaskRecordresult=setTaskFromReuseOrCreateNewTask(taskToAffiliate);}elseif(mSourceRecord!=null){result=setTaskFromSourceRecord();}elseif(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.result=setTaskToCurrentTopOrCreateNewTask();}//...if(mDoResume){finalActivityRecordtopTaskActivity=mStartActivity.getTaskRecord().topRunningActivityLocked();if(!mTargetStack.isFocusable()||(topTaskActivity!=null&&topTaskActivity.mTaskOverlay&&mStartActivity!=topTaskActivity)){// If the activity is not focusable, we can't resume it, but still would like to// make sure it becomes visible as it starts (this will also trigger entry// animation). An example of this are PIP activities.// Also, we don't want to resume activities in a task that currently has an overlay// as the starting activity just needs to be in the visible paused state until the// over is removed.mTargetStack.ensureActivitiesVisibleLocked(mStartActivity,0,!PRESERVE_WINDOWS);// Go ahead and tell window manager to execute app transition for this activity// since the app transition will not be triggered through the resume channel.mTargetStack.getDisplay().mDisplayContent.executeAppTransition();}else{// If the target stack was not previously focusable (previous top running activity// on that stack was not visible) then any prior calls to move the stack to the// will not update the focused stack. If starting the new activity now allows the// task stack to be focusable, then ensure that we now update the focused stack// accordingly.if(mTargetStack.isFocusable()&&!mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)){mTargetStack.moveToFront("startActivityUnchecked");}//③mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack,mStartActivity,mOptions);}}elseif(mStartActivity!=null){mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());}mRootActivityContainer.updateUserStack(mStartActivity.mUserId,mTargetStack);mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),preferredWindowingMode,mPreferredDisplayId,mTargetStack);returnSTART_SUCCESS;}
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.javabooleanresumeFocusedStacksTopActivities(ActivityStacktargetStack,ActivityRecordtarget,ActivityOptionstargetOptions){if(!mStackSupervisor.readyToResume()){returnfalse;}booleanresult=false;if(targetStack!=null&&(targetStack.isTopStackOnDisplay()||getTopDisplayFocusedStack()==targetStack)){result=targetStack.resumeTopActivityUncheckedLocked(target,targetOptions);}for(intdisplayNdx=mActivityDisplays.size()-1;displayNdx>=0;--displayNdx){booleanresumedOnDisplay=false;finalActivityDisplaydisplay=mActivityDisplays.get(displayNdx);for(intstackNdx=display.getChildCount()-1;stackNdx>=0;--stackNdx){finalActivityStackstack=display.getChildAt(stackNdx);//获取要启动的Activity所有栈的栈顶的不是处于停止状态的ActivityRecordfinalActivityRecordtopRunningActivity=stack.topRunningActivityLocked();if(!stack.isFocusableAndVisible()||topRunningActivity==null){continue;}if(stack==targetStack){// Simply update the result for targetStack because the targetStack had// already resumed in above. We don't want to resume it again, especially in// some cases, it would cause a second launch failure if app process was dead.resumedOnDisplay|=result;continue;}if(display.isTopStack(stack)&&topRunningActivity.isState(RESUMED)){// Kick off any lingering app transitions form the MoveTaskToFront operation,// but only consider the top task and stack on that display.stack.executeAppTransition(targetOptions);}else{resumedOnDisplay|=topRunningActivity.makeActiveIfNeeded(target);}}if(!resumedOnDisplay){// In cases when there are no valid activities (e.g. device just booted or launcher// crashed) it's possible that nothing was resumed on a display. Requesting resume// of top activity in focused stack explicitly will make sure that at least home// activity is started and resumed, and no recursion occurs.finalActivityStackfocusedStack=display.getFocusedStack();if(focusedStack!=null){//调用ActivityStack的resumeTopActivityUncheckedLocked方法focusedStack.resumeTopActivityUncheckedLocked(target,targetOptions);}}}returnresult;}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.javabooleanresumeTopActivityUncheckedLocked(ActivityRecordprev,ActivityOptionsoptions){if(mInResumeTopActivity){// Don't even start recursing.returnfalse;}booleanresult=false;try{// Protect against recursion.mInResumeTopActivity=true;result=resumeTopActivityInnerLocked(prev,options);// When resuming the top activity, it may be necessary to pause the top activity (for// example, returning to the lock screen. We suppress the normal pause logic in// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here// to ensure any necessary pause logic occurs. In the case where the Activity will be// shown regardless of the lock screen, the call to// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.finalActivityRecordnext=topRunningActivityLocked(true/* focusableOnly */);if(next==null||!next.canTurnScreenOn()){checkReadyForSleep();}}finally{mInResumeTopActivity=false;}returnresult;}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.javavoidstartSpecificActivity(ActivityRecordr,booleanandResume,booleancheckConfig){// Is this activity's application already running?//获取即将启动的Activity的所在的应用程序进程//①finalWindowProcessControllerwpc=mService.getProcessController(r.processName,r.info.applicationInfo.uid);booleanknownToBeDead=false;//②if(wpc!=null&&wpc.hasThread()){try{//③realStartActivityLocked(r,wpc,andResume,checkConfig);return;}catch(RemoteExceptione){Slog.w(TAG,"Exception when starting activity "+r.intent.getComponent().flattenToShortString(),e);}// If a dead object exception was thrown -- fall through to// restart the application.knownToBeDead=true;}// Suppress transition until the new activity becomes ready, otherwise the keyguard can// appear for a short amount of time before the new process with the new activity had the// ability to set its showWhenLocked flags.if(getKeyguardController().isKeyguardLocked()){r.notifyUnknownVisibilityLaunched();}finalbooleanisTop=andResume&&r.isTopRunningActivity();//创建进程mService.startProcessAsync(r,knownToBeDead,isTop,isTop?"top-activity":"activity");}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.javabooleanrealStartActivityLocked(ActivityRecordr,WindowProcessControllerproc,booleanandResume,booleancheckConfig)throwsRemoteException{// Create activity launch transaction.//创建ClientTransaction 传入WindowProcessController的IApplicationThread//frameworks/base/core/java/android/app/servertransaction/ClientTransaction.javafinalClientTransactionclientTransaction=ClientTransaction.obtain(proc.getThread(),r.appToken);finalDisplayContentdc=r.getDisplay().mDisplayContent;clientTransaction.addCallback(LaunchActivityItem.obtain(newIntent(r.intent),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,proc.getReportedProcState(),r.icicle,r.persistentState,results,newIntents,dc.isNextTransitionForward(),proc.createProfilerInfoIfNeeded(),r.assistToken));// Set desired final state.//创建ActivityLifecycleItem//frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.javafinalActivityLifecycleItemlifecycleItem;if(andResume){lifecycleItem=ResumeActivityItem.obtain(dc.isNextTransitionForward());}else{lifecycleItem=PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// Schedule transaction.mService.getLifecycleManager().scheduleTransaction(clientTransaction);returntrue;}
//ClientLifecycleManager.javavoidscheduleTransaction(ClientTransactiontransaction)throwsRemoteException{finalIApplicationThreadclient=transaction.getClient();transaction.schedule();if(!(clientinstanceofBinder)){// If client is not an instance of Binder - it's a remote call and at this point // safe to recycle the object. All objects used for local calls will be recycled // the transaction is executed on client in ActivityThread.transaction.recycle();}}
classHextendsHandler{publicvoidhandleMessage(Messagemsg){if(DEBUG_MESSAGES)Slog.v(TAG,">>> handling: "+codeToString(msg.what));switch(msg.what){caseEXECUTE_TRANSACTION:finalClientTransactiontransaction=(ClientTransaction)msg.obj;mTransactionExecutor.execute(transaction);if(isSystem()){// Client transactions inside system process are recycled on the client side// instead of ClientLifecycleManager to avoid being cleared before this// message is handled.transaction.recycle();}// TODO(lifecycler): Recycle locally scheduled transactions.break;}Objectobj=msg.obj;if(objinstanceofSomeArgs){((SomeArgs)obj).recycle();}if(DEBUG_MESSAGES)Slog.v(TAG,"<<< done: "+codeToString(msg.what));}}
//TransactionExecutor.javapublicvoidexecute(ClientTransactiontransaction){if(DEBUG_RESOLVER)Slog.d(TAG,tId(transaction)+"Start resolving transaction");finalIBindertoken=transaction.getActivityToken();if(token!=null){finalMap<IBinder,ClientTransactionItem>activitiesToBeDestroyed=mTransactionHandler.getActivitiesToBeDestroyed();finalClientTransactionItemdestroyItem=activitiesToBeDestroyed.get(token);if(destroyItem!=null){if(transaction.getLifecycleStateRequest()==destroyItem){// It is going to execute the transaction that will destroy activity with the// token, so the corresponding to-be-destroyed record can be removed.activitiesToBeDestroyed.remove(token);}if(mTransactionHandler.getActivityClient(token)==null){// The activity has not been created but has been requested to destroy, so all// transactions for the token are just like being cancelled.Slog.w(TAG,tId(transaction)+"Skip pre-destroyed transaction:\n"+transactionToString(transaction,mTransactionHandler));return;}}}if(DEBUG_RESOLVER)Slog.d(TAG,transactionToString(transaction,mTransactionHandler));executeCallbacks(transaction);executeLifecycleState(transaction);mPendingActions.clear();if(DEBUG_RESOLVER)Slog.d(TAG,tId(transaction)+"End resolving transaction");}
/** Cycle through all states requested by callbacks and execute them at proper times. */@VisibleForTestingpublicvoidexecuteCallbacks(ClientTransactiontransaction){finalList<ClientTransactionItem>callbacks=transaction.getCallbacks();if(callbacks==null||callbacks.isEmpty()){// No callbacks to execute, return early.return;}if(DEBUG_RESOLVER)Slog.d(TAG,tId(transaction)+"Resolving callbacks in transaction");finalIBindertoken=transaction.getActivityToken();ActivityClientRecordr=mTransactionHandler.getActivityClient(token);// In case when post-execution state of the last callback matches the final state requested// for the activity in this transaction, we won't do the last transition here and do it when// moving to final state instead (because it may contain additional parameters from server).finalActivityLifecycleItemfinalStateRequest=transaction.getLifecycleStateRequest();finalintfinalState=finalStateRequest!=null?finalStateRequest.getTargetState():UNDEFINED;// Index of the last callback that requests some post-execution state.finalintlastCallbackRequestingState=lastCallbackRequestingState(transaction);finalintsize=callbacks.size();for(inti=0;i<size;++i){//获取itemfinalClientTransactionItemitem=callbacks.get(i);if(DEBUG_RESOLVER)Slog.d(TAG,tId(transaction)+"Resolving callback: "+item);finalintpostExecutionState=item.getPostExecutionState();finalintclosestPreExecutionState=mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());if(closestPreExecutionState!=UNDEFINED){cycleToPath(r,closestPreExecutionState,transaction);}//执行executeitem.execute(mTransactionHandler,token,mPendingActions);item.postExecute(mTransactionHandler,token,mPendingActions);if(r==null){// Launch activity request will create an activity record.r=mTransactionHandler.getActivityClient(token);}if(postExecutionState!=UNDEFINED&&r!=null){// Skip the very last transition and perform it by explicit state request instead.finalbooleanshouldExcludeLastTransition=i==lastCallbackRequestingState&&finalState==postExecutionState;cycleToPath(r,postExecutionState,shouldExcludeLastTransition,transaction);}}}
/** * Extended implementation of activity launch. Used when server requests a launch or relaunch. */@OverridepublicActivityhandleLaunchActivity(ActivityClientRecordr,PendingTransactionActionspendingActions,IntentcustomIntent){// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();mSomeActivitiesChanged=true;if(r.profilerInfo!=null){mProfiler.setProfiler(r.profilerInfo);mProfiler.startProfiling();}// Make sure we are running with the most recent config.handleConfigurationChanged(null,null);if(localLOGV)Slog.v(TAG,"Handling launch of "+r);// Initialize before creating the activityif(!ThreadedRenderer.sRendererDisabled&&(r.activityInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED)!=0){HardwareRenderer.preload();}WindowManagerGlobal.initialize();// Hint the GraphicsEnvironment that an activity is launching on the process.GraphicsEnvironment.hintActivityLaunch();finalActivitya=performLaunchActivity(r,customIntent);if(a!=null){r.createdConfig=newConfiguration(mConfiguration);reportSizeConfigurations(r);if(!r.activity.mFinished&&pendingActions!=null){pendingActions.setOldState(r.state);pendingActions.setRestoreInstanceState(true);pendingActions.setCallOnPostCreate(true);}}else{// If there was an error, for any reason, tell the activity manager to stop us.try{ActivityTaskManager.getService().finishActivity(r.token,Activity.RESULT_CANCELED,null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);}catch(RemoteExceptionex){throwex.rethrowFromSystemServer();}}returna;}
privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){//获取ActivityInfoActivityInfoaInfo=r.activityInfo;if(r.packageInfo==null){//获取Apk文件的描述类LoadedApkr.packageInfo=getPackageInfo(aInfo.applicationInfo,r.compatInfo,Context.CONTEXT_INCLUDE_CODE);}ComponentNamecomponent=r.intent.getComponent();if(component==null){component=r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if(r.activityInfo.targetActivity!null){component=newComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}//创建要启动Activity的上下文环境ContextImplappContext=createBaseContextForActivity(r);Activityactivity=null;try{//获取类加载器java.lang.ClassLoadercl=appContext.getClassLoader();//用类加载器创建该Activity的实例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(Exceptione){//...}try{//创建ApplicationApplicationapp=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){CharSequencetitle=r.activityInfo.loadLabel(appContext.getPackageManager());Configurationconfig=newConfiguration(mCompatConfiguration);if(r.overrideConfig!=null){config.updateFrom(r.overrideConfig);}if(DEBUG_CONFIGURATION)Slog.v(TAG,"Launching activity "+r.activityInfo.name+" with config "+config);Windowwindow=null;if(r.mPendingRemoveWindow!=null&&r.mPreserveWindow){window=r.mPendingRemoveWindow;r.mPendingRemoveWindow=null;r.mPendingRemoveWindowManager=null;}appContext.setOuterContext(activity);//初始化Activityactivity.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,r.assistToken);if(customIntent!=null){activity.mIntent=customIntent;}r.lastNonConfigurationInstances=null;checkAndBlockForNetworkAccess();activity.mStartedActivity=false;inttheme=r.activityInfo.getThemeResource();if(theme!=0){activity.setTheme(theme);}activity.mCalled=false;if(r.isPersistable()){//启动ActivitymInstrumentation.callActivityOnCreate(activity,r.state,r.persistentState);}else{mInstrumentation.callActivityOnCreate(activity,r.state);}if(!activity.mCalled){thrownewSuperNotCalledException("Activity "+r.intent.getComponent().toShortString()+" did not call through to super.onCreate()");}r.activity=activity;}r.setState(ON_CREATE);// updatePendingActivityConfiguration() reads from mActivities to update// ActivityClientRecord which runs in a different thread. Protect modifications to// mActivities to avoid race.synchronized(mResourcesManager){mActivities.put(r.token,r);}}catch(SuperNotCalledExceptione){throwe;}catch(Exceptione){if(!mInstrumentation.onException(activity,e)){thrownewRuntimeException("Unable to start activity "+component+": "+e.toString(),e);}}returnactivity;}