前言activity启动的时候会说到activitystack,taskstack,activitytaskstack等词,但是如果你仔细问一下这些名词代表什么?通过什么外观?一个ActivityRecord对应一个Activity,保存了一个Activity的所有信息;但是一个Activity可能有多个ActivityRecords,因为Activity可以启动多次,这主要取决于它的启动方式;一个TaskRecord由一个或多个ActivityRecords组成,这就是我们常说的任务栈,具有后进先出的特点;ActivityStack用于管理TaskRecord,包括多个TaskRecord;今天我们就来说说如何管理activity和taskstack等;、任务栈源码解析1、ActivityRecordActivityRecord:历史栈中的一个条目,代表一个activityfinalclassActivityRecordextendsConfigurationContainerimplementsAppWindowContainerListener{finalActivityManagerServiceservice;//ownerfinalIApplicationToken.StubappToken;//windowmanagertokenAppWindowContainerControllermWindowContainerController;finalActivityInfoinfo;//allaboutmefinalApplicationInfoappInfo;//informationaboutactivity'sapp//省略其他成员变量//TaskRecordprivateTaskRecordtaskwhereActivityRecord所在;//thetaskthisisin.//构造方法需要传递很多信息ActivityRecord(ActivityManagerService_service,ProcessRecord_caller,int_launchedFromPid,int_launchedFromUid,String_launchedFromPackage,Intent_intent,String_resolvedType,ActivityInfoaInfo,Configuration_configuration,com.android.server.am.ActivityRecord_resultTo,String_resultWho,int_reqCode,boolean_componentSpecified,boolean_rootVoiceInteraction,ActivityStackSupervisorsupervisor,ActivityOptionsoptions,com.android.server.am.ActivityRecordsourceRecord){}}实际上,ActivityRecord中有大量的成员变量,包含了一个Activity的所有信息;ActivityRecord中的成员变量task表示它所在的TaskRecord,所以可以看出:ActivityRecord已经和TaskRecord建立了关系;whenstartActivity()willcreateanActivityRecordclassActivityStarter{privateintstartActivity(IApplicationThreadcaller,Intentintent,IntentephemeralIntent,StringresolvedType,ActivityInfoaInfo,ResolveInforInfo,IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,IBinderresultTo,StringresultWho,intrequestCode,intcallingPid,intcallingUid,StringcallingPackage,intrealCallingPid,intrealCallingUid,intstartFlags,ActivityOptionsoptions,booleanignoreTargetSecurity,booleancomponentSpecified,com.android.server.am.ActivityRecord[]outActivity,TaskRecordinTask){//其他代码略,resultRecord,resultWho,requestCode,componentSpecified,voiceSession!=null,mSupervisor,options,sourceRecord);//其他代码省略}}2、TaskRecordTaskRecord内部维护了一个ArrayList,用于保存ActivityRecord;finalclassTaskRecordextendsConfigurationContainerimplementsTaskWindowContainerListenerId/ArrayinttaActivityRecord>mActivities;//使用一个ArrayList来保存所有的ActivityRecordprivateActivityStackmStack;//TaskRecord所在的ActivityStack//构造方法TaskRecord(ActivityManagerServiceservice,int_taskId,ActivityInfoinfo,Intent_intent,IVoiceInteractionSession_voiceSession,IVoiceInteractor_voiceInteractor,inttype){}//添加Activity到顶部voidaddActivityToTop(com.android.server.am.ActivityRecordr){addActivityAtIndex(mActivities.size(),r);}//添加Activity到指定索引位置voidaddActivityAtIndex(intindex,ActivityRecordr){//...r.setTask(this);//为ActivityRecord设置TaskRecord,也就是这里建立的连接//...index=Math.min(size,index);mActivities.add(index,r);//添加到mActivities//...}//其他代码略}可以看到在TaskRecord中使用了一个ArrayList来保存所有的ActivityRecords;similarly,TaskRecord中的mStack表示其所在的ActivityStack;startActivity()时也会创建一个TaskRecord;classActivityStarter{privateintsetTaskFromReuseOrCreateNewTask(TaskRecordtaskToAffiliate,intpreferredLaunchStackId,ActivityStacktopStack){mTargetStack=computeStackFocus(mStartActivity,true,mLaunchBounds,mLaunchFlags,mOptions);if(mReuseTask==null){//创建createTaskRecord实际上调用了ActivityStack中的createTaskRecord()方法。activityStack会讨论finalTask??Recordtask=mTargetStack.createTaskRecord(mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),mNewTaskInfo!=null?mNewTaskInfo.mStartActivity信息,mNewTaskIntent!=null?mNewTaskIntent:mIntent,mVoiceSession,mVoiceInteractor*/toskinTop,!mLaunchTaskIntent,m开始活动.mActivityType);//其他代码省略}}}3.ActivityStackActivityStack内部维护了一个ArrayList来管理TaskRecord;来保存TaskRecordfinalintmStackId;protectedfinalActivityStackSupervisormStackSupervisor;//持有一个ActivityStackSupervisor,所有的运行中的ActivityStacks都过熬过/构造方法ActivityStack(ActivityStackSupervisor.ActivityDisplaydisplay,intstackId,ActivityStackSupervisorsupervisor,RecentTasksrecentTasks,booleanonTop){}TaskRecordcreateTaskRecord(inttaskId,ActivityInfoinfo,Intentintent,IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,booleantoTop,inttype){//CreateataskTaskRecordtask=newTaskRecord(mService,taskId,info,intent,voiceSession,voiceInteractor,type);//添加任务到ActivityStackaddTask(task,toTop,"createTaskRecord");//其他代码略returntask;}//添加任务voidaddTask(finalTask??Recordtask,finalbooleantoTop,Stringreason){addTask(task,toTop?MAX_VALUE:0,true/*schedulePictureInPictureModeChange*/,reason);//其他代码省略}//添加Task到指定位置voidaddTask(finalTask??Recordtask,intposition,booleanschedulePictureInPictureModeChange,Stringreason){mTaskHistory.remove(task);//如果存在则先移除//...mTaskHistory.add(position,task);//添加任务到mTaskHistorytask.setStack(this);//设置ActivityStackforTaskRecord//...}//其他代码}看到ActivityStack使用一个ArrayList来保存TaskRecord;此外,ActivityStack还持有ActivityStackSupervisor对象,用于管理ActivityStacks;ActivityStack是由ActivityStackSupervisor创建的,实际ActivityStackSupervisor是用来管理ActivityStack的,继续看下面对ActivityStackSupervisor的分析;4、ActivityStackSupervisorActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的;ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的;ActivityStackmFocusedStack;//管理非Launcher相关的任务//创建ActivityStackActivityStackcreateStack(intstackId,ActivityStackSupervisor.ActivityDisplaydisplay,booleanonTop){switch(stackId){casePINNED_STACK_ID://PinnedActivityStack是ActivityStack的子类returnnewPinnedActivityStack(display,stackId,this,mRecentTasks,onTop);default://创建一个ActivityStackIdisturnActivityStackIdisturnActivityStack,this,mRecentTasks,onTop);}}}ActivityStackSupervisor内部有两个不同的ActivityStack对象:mHomeStack和mFocusedStack,分别用来管理不同的任务;ActivityStackSupervisor包含创建ActivityStack对象的方法;AMS在初始化时会创建一个ActivityStackSupervisor对象;2.看启动过程中的任务栈和启动方式1.启动过程简单分析启动过程中涉及到的ActivityStack、TaskRecord、ActivityRecord、ActivityStackSupervisor。其实一张时序图就可以看的一清二楚。当startActivity第一次被创建时,ActivityRecord会根据需要创建一个TaskRecord,并将这个TaskRecord添加到ActivityStack中。将ActivityRecord添加到TaskRecord的栈顶2.启动模式下的任务栈①Standerd默认模式,每次启动Activity,都会创建一个新的Activity实例现在有AActivity,我们在A上启动B,然后在B上启动A,流程如图②singleTop如果要启动的Activity已经在栈顶,则不会重新创建Activity,只会调用Activity的onNewIntent()方法。如果要启动的Activity不在栈顶,则重新创建一个Activity的实例;现在有一个ActivityA,我们在A上以standerd模式启动B,然后在B上以singleTop模式启动A,流程如图,这里会创建一个新的A实例B,如果B是在singleTop模式下启动,B不会被重新创建,只会调用onNewIntent()方法,流程如图③singleTask如果要启动的Activity已经存在于期望的所属栈中,则Activity实例不会创建完成,栈中Activity上的所有Activity都会被弹出,同时调用Activity的onNewIntent()方法。如果要启动的Activity在它想要属于的堆栈中不存在,而堆栈中存在,则创建该Activity的实例。如果要启动的Activity所在的栈不存在,则必须先新建一个栈,然后创建一个Activity的实例并压入新的栈中现在有了AActivity,我们在standerd中在A上启动B模式,然后在B上以singleTask模式启动A,流程如图④singleInstance与singleTask基本相同,不同的是启动Activity时,必须先新建一个栈,然后再创建Activity实例并将其推入新栈中,新栈中只会有这一个Activity实例;现在有一个ActivityA,我们在A上以singleInstance方式启动B,流程如图:3.启动FlagstartActivity()时,在Intent中添加相应的flag来指定启动方式,这个的优先级method会高于AndroidManifest中定义的;但AndroidManifest中只能定义四种启动方式:standard、singleTop、singleTask、singleInstance,还有很多种Intent标志。有关详细信息,请参阅文档。让我们看一下这里的一些标志:FLAG_ACTIVITY_NEW_TASK:与launchMode中的singleTask相同。FLAG_ACTIVITY_SINGLE_TOP:与launchMode中的singleTop相同。FLAG_ACTIVITY_CLEAR_TOP:launchMode中没有对应的值。如果要启动的Activity已经存在于栈中,则将其之上的所有Activity弹出栈。singleTask默认有这个flag的作用【责任编辑:吴小燕TEL:(010)68476606】
