文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android源码进阶之ActivityRecord、TaskRecord、ActivityStack以及启动模式详细分析

2024-12-14 01:36

关注

一个ActivityRecord对应一个Activity,保存了一个Activity的所有信息;但是一个Activity可能会有多个ActivityRecord,因为Activity可以被多次启动,这个主要取决于其启动模式;

一个TaskRecord由一个或者多个ActivityRecord组成,这就是我们常说的任务栈,具有后进先出的特点;

ActivityStack则是用来管理TaskRecord的,包含了多个TaskRecord;

今天我们就来聊聊怎么管理activity以及任务栈等;

一、任务栈源码解析

1、ActivityRecord

ActivityRecord:历史栈中的一个条目,代表一个activity

  1. final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener { 
  2.         final ActivityManagerService service; // owner 
  3.         final IApplicationToken.Stub appToken; // window manager token 
  4.         AppWindowContainerController mWindowContainerController; 
  5.         final ActivityInfo info; // all about me 
  6.         final ApplicationInfo appInfo; // information about activity's app 
  7.         //省略其他成员变量 
  8.         //ActivityRecord所在的TaskRecord 
  9.         private TaskRecord task;        // the task this is in
  10.         //构造方法,需要传递大量信息 
  11.         ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid, 
  12.                        int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType, 
  13.                        ActivityInfo aInfo, Configuration _configuration, 
  14.                        com.android.server.am.ActivityRecord _resultTo, String _resultWho, int _reqCode, 
  15.                        boolean _componentSpecified, boolean _rootVoiceInteraction, 
  16.                        ActivityStackSupervisor supervisor, ActivityOptions options, 
  17.                        com.android.server.am.ActivityRecord sourceRecord) { 
  18.         } 
  19.     } 

startActivity()时会创建一个ActivityRecord

  1. class ActivityStarter { 
  2.         private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 
  3.                                   String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 
  4.                                   IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 
  5.                                   IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, 
  6.                                   String callingPackage, int realCallingPid, int realCallingUid, int startFlags, 
  7.                                   ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, 
  8.                                   com.android.server.am.ActivityRecord[] outActivity, TaskRecord inTask) { 
  9.             //其他代码略 
  10.             ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, 
  11.                     callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), 
  12.                     resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null
  13.                     mSupervisor, options, sourceRecord); 
  14.             //其他代码略 
  15.         } 
  16.     } 

2、TaskRecord

TaskRecord,内部维护一个ArrayList用来保存ActivityRecord;

  1. final class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener { 
  2.         final int taskId;       //任务ID 
  3.         final ArrayList mActivities;   //使用一个ArrayList来保存所有的ActivityRecord 
  4.         private ActivityStack mStack;   //TaskRecord所在的ActivityStack 
  5.         //构造方法 
  6.         TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent, 
  7.                    IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, int type) { 
  8.         } 
  9.         //添加Activity到顶部 
  10.         void addActivityToTop(com.android.server.am.ActivityRecord r) { 
  11.             addActivityAtIndex(mActivities.size(), r); 
  12.         } 
  13.         //添加Activity到指定的索引位置 
  14.         void addActivityAtIndex(int index, ActivityRecord r) { 
  15.             //... 
  16.             r.setTask(this);//为ActivityRecord设置TaskRecord,就是这里建立的联系 
  17.             //... 
  18.             index = Math.min(sizeindex); 
  19.             mActivities.add(index, r);//添加到mActivities 
  20.             //... 
  21.         } 
  22.         //其他代码略 
  23.     } 

startActivity()时也会创建一个TaskRecord;

  1. class ActivityStarter { 
  2.         private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate, int preferredLaunchStackId, ActivityStack topStack) { 
  3.             mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags, mOptions); 
  4.             if (mReuseTask == null) { 
  5.                 //创建一个createTaskRecord,实际上是调用ActivityStack里面的createTaskRecord()方法,ActivityStack下面会讲到 
  6.                 final TaskRecord task = mTargetStack.createTaskRecord( 
  7.                         mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), 
  8.                         mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, 
  9.                         mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession, 
  10.                         mVoiceInteractor, !mLaunchTaskBehind , mStartActivity.mActivityType); 
  11.                 //其他代码略 
  12.             } 
  13.         } 
  14.     } 

3、ActivityStack

ActivityStack,内部维护了一个ArrayList,用来管理TaskRecord;

  1. class ActivityStack extends ConfigurationContainer implements StackWindowListener { 
  2.         private final ArrayList mTaskHistory = new ArrayList<>();//使用一个ArrayList来保存TaskRecord 
  3.         final int mStackId; 
  4.         protected final ActivityStackSupervisor mStackSupervisor;//持有一个ActivityStackSupervisor,所有的运行中的ActivityStacks都通过它来进行管理 
  5.         //构造方法 
  6.         ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId, 
  7.                       ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) { 
  8.         } 
  9.         TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, 
  10.                                     IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 
  11.                                     boolean toTop, int type) { 
  12.             //创建一个task 
  13.             TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession, voiceInteractor, type); 
  14.             //将task添加到ActivityStack中去 
  15.             addTask(task, toTop, "createTaskRecord"); 
  16.             //其他代码略 
  17.             return task; 
  18.         } 
  19.         //添加Task 
  20.         void addTask(final TaskRecord task, final boolean toTop, String reason) { 
  21.             addTask(task, toTop ? MAX_VALUE : 0, true , reason); 
  22.             //其他代码略 
  23.         } 
  24.         //添加Task到指定位置 
  25.         void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange, 
  26.                      String reason) { 
  27.             mTaskHistory.remove(task);//若存在,先移除 
  28.             //... 
  29.             mTaskHistory.add(position, task);//添加task到mTaskHistory 
  30.             task.setStack(this);//为TaskRecord设置ActivityStack 
  31.             //... 
  32.         } 
  33.         //其他代码略 
  34.     } 

4、ActivityStackSupervisor

ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的;

  1. ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的; 
  2.     public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener { 
  3.         ActivityStack mHomeStack;//管理的是Launcher相关的任务 
  4.         ActivityStack mFocusedStack;//管理非Launcher相关的任务 
  5.         //创建ActivityStack 
  6.         ActivityStack createStack(int stackId, ActivityStackSupervisor.ActivityDisplay display, boolean onTop) { 
  7.             switch (stackId) { 
  8.                 case PINNED_STACK_ID: 
  9.                     //PinnedActivityStack是ActivityStack的子类 
  10.                     return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop); 
  11.                 default
  12.                     //创建一个ActivityStack 
  13.                     return new ActivityStack(display, stackId, this, mRecentTasks, onTop); 
  14.             } 
  15.         } 
  16.     } 

二、启动流程和启动模式看任务栈

1、启动流程

启动Activity过程中涉及到的ActivityStack、TaskRecord、ActivityRecord、ActivityStackSupervisor进行简单的分析,实际上一张时序图就可以看明白了

2、启动模式中的任务栈

①standerd

默认模式,每次启动Activity都会创建一个新的Activity实例

现在有个A Activity,我们在A上面启动B,再然后在B上面启动A,其过程如图所示

②singleTop

现在有个A Activity,我们在A以standerd模式上面启动B,然后在B上面以singleTop模式启动A,其过程如图所示,这里会新创建一个A实例

B上面以singleTop模式启动B的话,则不会重新创建B,只会调用onNewIntent()方法,其过程如图所示

③singleTask

现在有个A Activity,我们在A以standerd模式上面启动B,然后在B上面以singleTask模式启动A,其过程如图所示

④singleInstance

基本和singleTask一样,不同的是启动Activity时,首先要创建在一个新栈,然后创建该Activity实例并压入新栈中,新栈中只会存在这一个Activity实例;

现在有个A Activity,我们在A以singleInstance模式上面启动B,其过程如图所示:

3、启动Flag

startActivity()时往Intent 中加入相应的标志来指定启动模式,这种方式的优先级会比在AndroidManifest中定义的优先级高;但是AndroidManifest中只能定义四种启动方式:standard、singleTop、singleTask、singleInstance,而Intent的flag则有很多种。具体的可以看看文档,我们这里看看部分flag:

 

来源:Android开发编程内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯