Activity 启动模式,熟知的就是 standard、singleTop、singleTask、singleInstance
注意点:
任务栈 -- 所有Activity继承Application 的任务栈名称,即包名。
只有 singleTask 启动模式的Activity 单独设置任务栈名称有意义。
任务栈名称不可与包名一致,设置方式为在清单文件。
android:taskAffinity="com.yanlong.task1"
1、standard 启动模式,谁加载我,我进入谁的任务栈;
2、ApplicationContext 启动 standard 模式的Activity 报错,因为 非Activity类型的Context 无所谓 任务栈。解决方法,给待启动Activity指定 FLAG_ACTIVITY_NEW_TASK
Intent intent = new Intent(); intent.setClass(MainActivity.this,SecondActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);3、singleTop:如果启动的新AC已经属于栈顶,那么会调用 onNewIntent。
4、singleTask:如果存在,多次启动,调用onNewIntent。
重要:singleTask 启动方式 --- 先检查是否有所需 任务栈,再检查是否有所需实例。
举例:
任务栈名称 默认包名 如 com.yanlong.myapplication
任务栈名称 自定义栈名 如 com.yanlong.task
A:MainActivity 任务栈名称 默认包名,默认打开 standard
B:SecondActivity 任务栈名称 默认包名,打开方式 standard
C:ThreadActivity 任务栈名称 自定义栈名,打开方式 singleTask
D:FourActivity 任务栈名称 自定义栈名,打开方式 singleTask
启动流程 A->B->C->D->B
A启动B,由于B是 standard,那么B直接进入 默认包名栈
B启动C,由于C是 singleTask,那么C先查找 自定义栈名,没有找到,那么先创建 自定义栈名,然后创建C实例,压入自定义栈名任务栈
C启动D,由于自定义栈名已经存在,然后查找该栈名内是否有 D实例,没有找到,那么创建D实例,压入自定义栈名任务栈
D启动B,由于B是 standard,那么B直接进入 自定义栈名任务栈
所以最后结果
默认栈内:A B
自定义栈内:C D B
TaskAffinity属性主要和singleTask启动模式或者 allowTaskReparenting属性配对使用,在其他情况下没有意义。另外,任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity位于暂停状态,用户可以通过 切换将后台任务栈再次调到前台。
这里前台任务栈 后台任务栈不是很明朗,根据书中所写,我个人见解是,当前显示的 Activity所在的栈区是前台任务栈,其他的任务栈都是后台任务栈。希望有了解的留言纠正。
重点:
当TaskAffinity和allowTaskReparenting结合的时候,会产生特殊效果
应用 M,应用 N
N中 Activity N-A,属性 allowTaskReparenting 为 true
M 启动了 N-A。然后按Home回到桌面,单击N的桌面图标,显示界面不是 N的MainActivity 而是 N-A
解释:
M 启动了 N-A,这时候 N-A 只能运行在 M的任务栈中,但是N-A属于N应用,正常情况下,他的TaskAffinity值肯定和M不同,因为包名不同。所以当N启动时,N会创建自己的任务栈,这时候系统发现 N-A原本想要的任务栈被创建了,所以就把N-A从M的任务栈 转移了过来。