前述
1.三个Activity,A、B、C、其中AB的启动模式为standard,C的启动模式为singleInstance,A–B–C依次启动后,按下home键与back键操作,分析调用的生命周期方法。
2.要分析所执行的生命周期方法首先要对Android的启动模式有所了解。
Android的启动模式
1.为什么需要启动模式?先来了解Activity任务栈,按照官方的定义:任务是用户在执行某项工作时与之互动的一系列Activity的集合,这些被实例化的Activity按照一定的顺序排列在返回栈
中,并且这些栈中的Activity不能够被重新排列。而有时候我们并不希望同一个类型的Activity被反复创建,造成资源的消耗,而android:launchMode
设定的四种启动模式,配合返回栈可以处理更加复杂的应用场景。另外返回栈又分为前台栈与后台栈,逐一分析四种启动模式。
standard
标准模式:也是Activity默认的启动模式,每次启动都会生成一个新的实例压入栈内。可以存在多个实例。
singleTop
栈顶复用模式:如果返回栈中存在实例并存在与栈顶,再次启动时不在重新创建,而是回调onNewInntent()方法,如不在栈顶则会重新创建。可能存在多个实例。
singleTask
栈内复用模式:如果返回栈中不存在该实例,则新创建并入栈。如果返回栈中已经存在实例并且不是栈顶,则清空实例上的所有Activity使其回到栈顶,回调onNewInntent()方法,如果恰哈位于栈顶则直接回调onNewInntent()方法。单个实例。
singleInstance
唯一实例:加强singleTask,单独栈,同样的如果已经存在实例,回调onNewInntent()方法。单个实例(单个栈)。
FLAG_ACTIVITY_NEW_TASK
If set, this activity will become the start of a new task on this history stack。这是官网的解释,被启动Activity将会是目标task的根Activity。非Activity启动的Activity需要显示的设置此标志位,主要侧重点在于task。多配合taskAffinity使用,假设有task1与task2两个栈。将要启动的Activity(A)的taskAffinity为task2。
1.A与task2都未创建,则创建task2,实例化A,移动到前台。
2.task2已经存在,并且不含有A的实例,如果task2在后台栈,则task2被置于前台,A被创建压入栈顶。如果task2已经位于前台,则直接创建A置于栈顶。
3.task2与A都已经存在,如果A为task2的根Activity,此时若task2,位于后台,则会被移动到前台,A不在被创建;如果A不是根Activity则重新创建A。
FLAG_ACTIVITY_CLEAR_TASK
配合FLAG_ACTIVITY_NEW_TASK一起使用,目标栈task已经存在,则清空栈,将要被创建的Activity作为根Activity,目标栈不存在则创建。
FLAG_ACTIVITY_CLEAR_TOP
清空目标Activity上的所有Activity,如果目标Activity没有设置可复用的launchMode,则finish后重新创建在入栈,也即是目标Activity是否复用看情况而定。
FLAG_ACTIVITY_SINGLE_TOP
类似于launchMode中设置的singleTop。
分析上述问题中的ABC生命周期
1.由于C为singleInstance,启动C之后按下home,从桌面launch图标点击此时出现的会是什么页面?答案是A或者B。首先,AB存在与同一个task,当被切入后台时,有可能被系统回收(在Api-R模拟器下测试发现)。启动C之后按下home键,AB被销毁后台task被系统回收,而Api-R以下的模拟器Api-28并没有销毁后台栈。此时按下launch图标出现的就是B页面。
2.在C页面按back键返回的是B页面。没什么特别的。
3.上述问题若改为B为singleInstance,依次启动。首先,可以明确的是AC是同一个task栈,而B单独一个task。所以当在C页面按下home键后在从launch图标点击时,此时出现的还是C,AC所在的栈被重新移动到前台(未销毁的情况)。若按back键,则返回A(AC同一个栈)。若在B页面按home与back的情况就不再赘述,分析此类问题其实就是对后台、前台任务栈的理解。