这是我参与「第四届青训营 」笔记创作活动的的第2天
[第四届青训营笔记创作活动]
Android基础组件(1):Activity
任务栈和返回栈
任务栈(task stack): Activity运行在栈结构中的,任务栈就是存储Activity活动实例的一个栈结构,先打开的Activity在栈的底部,新打开的Activity在栈的顶部
返回栈(back stack):
1、用户页面返回的时候是按着返回栈来进行的。
2、当调用的另一个任务栈的Activity为standard或singleTop时,会在调用者的任务栈直接创建一个新的活动实例,返回栈中只会加入调用的Activity一个
3、当调用另一个任务栈的Activity为singleStack或singleInstance时,此时为跨应用启动,会把整个后台任务栈带到前台,并且返回栈加入被调用的后台任务栈的所有Activity
4、一个返回栈中可能会包含来自不同任务栈的 Activity ,以维护正确的回退栈关系。这就是返回栈存在的意义。
Activity创建
第一步: 创建一个继承AppCompatActivity的java或kolitin文件
第二步: 创建一个Activity的布局文件
第三步: 在AndroidMainfest.xml上注册Activity
Acitivity生命周期
oncreate():创建时回调,一般在此处创建视图和绑定数据
onStart():已启动即将进入前台
onResume():开始与用户交互,位于Activity栈顶
onPause():Activity失去焦点或已暂停,Activity界面部分可见,下一个生命是onResume()或onStop()
onStop():Activity不再可见,下一个回调是onRestart()或onDestory()
onRestrat():重启已经停止的Activity,下一个回调的是onStart()
onDestroy():销毁Activity,释放该Activity的所有资源
onSaveInstanceState():在非正常时回调,用于保存数据,不支持持久化数据
onRestoreInstanceState()/onCreate():用于回复数据
Activity 启动模式
standard:
默认模式,允许Activity重复,每个activity创建时候会走一次onCreate、onStart、onResume
singleTop:
栈顶复用,不允许Activity连续重复,复用时会回到onNewIntent方法,不会走onCreate和onStart,只会走onResume
singleTask:
栈内复用,不允许栈内Activity重复,会寻找所属任务栈(默认或使用taskAffinity指定),复用时也是回调onNewIntent和onResume
SingleInstance:
全局复用,系统全局不允许Activity重复,首次启动时会创建新的 Activity 实例,并放入一个新的任务栈中,且 这个任务栈中只会有这一个实例。 后续启动不会再新建实例。
taskAffinity:
taskAffinity用于指定想要的任务栈
未显示声明taskAffinity的Activity都具有默认的任务栈,该任务栈的名称时应用包名
启动模式为standard或singleTop时,taskAffinity无效
启动模式为singleTask或singleInstance时,他会新建任务栈来存储活动实例
当在intent中设置FLAG_ACTIVITY_NEW_STACK也会使得taskAffinity生效
动态设置启动模式
使用启动标记可以实现动态的设置启动模式,如果同时在intent和清单文件中设置启动模式,intent中的优先级会更高
Intent.FLAG_ACTIVITY_NEW_TASK: 1、在不设置taskAffinity时,单独设置该标签不会创建新的任务栈,每次启动时都会创建新的Activity实例,不会栈内复用
2、在一个新的任务栈中启动 Activity 。如果想要的任务栈已经存在,并且其中已经运行着待启动的 Activity ,那么这个任务栈会被带到前台,并回调 onNewIntent() 。这个行为和 singleTask 一致。
3、从非Activity环境启动Activity,因为启动Activity时默认情况下会进入源Activity所在的任务栈中,所以如果在非Activity环境中启动Activity会抛出异常
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
是否创建新的任务栈会由taskAffinity决定。
Intent.FLAG_ACTIVITY_SINGLE_TOP:
等同于singleTop,栈顶复用。
Intent.FLAG_ACTIVITY_CLEAR_TOP:
1、单独使用时,如果在目标任务栈中已经存在调用的Activity活动实例并且**实例启动模式不为standard**则会把该实例之上的所有Activity弹出,回调onNewInstance。
2、如果**活动实例的启动模式为standard**则会弹出自己及以上的所有Activity
Intent.FLAG_ACTIVITY_NO_HISTORY: 栈中不保存新启动的活动实例
Intent.FLAG_ACTIVITY_CLEAR_TASK:
跳转到新页面的时候,Activity所属的任务栈中原有的实例被清空后该Activity成为根Activity,需要和Intent.FLAG_ACTIVITY_NEW_TASK配合使用
清单文件下的Activity属性
allowTaskReparenting
允许转移任务栈。设置allowTaskReparenting为true后,如果在app1调用app2的Activity时,app2的Activity会存在于app1的任务栈中,此时点击home键,打开app2的页面是,app2的被调用Activity也会转移到app2的任务栈的栈顶。
打开app1 -> 显示app1_av_1 -> 显示 app2_av_2 -> home键 -> 打开app2 -> 显示app2_av_2
clearTaskOnLaunch
如果任务栈的根Activity设置了clearTaskOnLaunch = true,home退出后,重新点击app图标进入(从任务列表进入无效),根Activity以上所有的实例弹出,只有根Activity设置有效。
alwaysRetainTaskState
与clearTaskOnLaunch相反,它尽量保证任务栈所有实例不被销毁,默认情况下任务栈可能会被各种原因清理。只有根Activity设置有效。
finishOnTaskLaunch
和clearTaskOnLaunch相似,但是返回时只清除finishOnTaskLaunch=true的Activity,他对包括根Activity在内的所有Activity有效。
excludeFromRecents 当前Activity所在任务栈是否在最近任务列表中显示。仅对根节点有效。
autoRemoveFromRecents 当app的任务栈为空时,自动不再最近任务列表中显示。
登录状态成功,跳转页面后不再返回登录界面模拟
基本功能:登录成功后,用户状态记录,按返回键不再返回登录界面。
问题:登录成功后跳转的Activity的模式为singleInstance,返回后依然为登录界面。
原因:因为singleInstance会创建一个新的任务栈,然后原来的任务栈会退到后台,singleInstance的任务栈走到前台,所以返回栈中有原来任务栈的Activity和singleInstance任务栈的Activity,此时FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK失效。同样如果调用的页面设置了taskAffinity也会失效,因为FLAG_ACITIVITY_NEW_TASK会激活taskAffinity。