关于活动的启动模式
- 关于活动的启动模式
- 活动的启动模式演示
- 活动的启动模式详解
- Intent的Flag详解
- FLAG_GRANT_READ_URI_PERMISSION
- FLAG_GRANT_WRITE_URI_PERMISSION
- FLAG_GRANT_PERSISTABLE_URI_PERMISSION
- FLAG_GRANT_PREFIX_URI_PERMISSION
- FLAG_DEBUG_LOG_RESOLUTION
- FLAG_FROM_BACKGROUND
- FLAG_ACTIVITY_BROUGHT_TO_FRONT
- FLAG_ACTIVITY_CLEAR_TASK
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- FLAG_ACTIVITY_FORWARD_RESULT
- FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
- FLAG_ACTIVITY_MULTIPLE_TASK
- FLAG_ACTIVITY_NEW_DOCUMENT
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_NO_ANIMATION
- FLAG_ACTIVITY_NO_HISTORY
- FLAG_ACTIVITY_NO_USER_ACTION
- FLAG_ACTIVITY_PREVIOUS_IS_TOP
- FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- FLAG_ACTIVITY_REORDER_TO_FRONT
- FLAG_ACTIVITY_SINGLE_TOP
- FLAG_ACTIVITY_TASK_ON_HOME
- FLAG_RECEIVER_REGISTERED_ONLY
关于活动的启动模式
注:启动模式详解部分全部来源于郭神的第二行代码
问题:如果想“跳转到某一活动后,点击返回按钮,直接退出应用”怎么办?
比如说,做退出登录功能,此时需要将界面跳转到登录界面。如果直接intent跳转,那么此时点击返回键,就会回退到退出登录之前的界面。这样显然是不符合需求的。
这个需求换成专业术语就是,跳转activity,如何清空之前全部的activity栈?
解决办法
跳转,并将栈中所有Activity清空
Intent intent = new Intent(A.this,B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
那么什么叫做栈?下面将会详细解答。
活动的启动模式演示
活动栈:
Android中的活动是可以层叠的。我们每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键会销毁最上面的活动,下面的一个活动就会重新显示出来。
可以层叠的原因,是因为Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(BackStack)。栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的活动,它会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。示意图2.19展示了返回栈是如何管理活动入栈出栈操作的。
关于一开始的问题
我们想达到的目的就是清空栈和将登陆Activity置于栈顶。
首先Intent调用startActivity的时候,会传递FLAG_ACTIVITY_CLEAR_TASK这个标志,那么这个标志将会销毁目标Activity和它之上的所有Activity(清空栈),重新创建目标Activity。关于Intent的标志位有很多,我在最后部分列出了详细列表。
那么FLAG_ACTIVITY_NEW_TASK又是什么呢?
这就涉及到活动的启动模式的知识了。
Activity有四种启动模式:standard、singTop、singleTask和singleInstance。
与intent的启动标志对应为:
部分Intent的标志位FLAG:
standard:Intent.FLAG_ACTIVITY_NEW_TASK
singTop:Intent.FLAG_ACTIVITY_SINGLE_TOP
演示
Standard
standard,活动的默认启动模式就是它。
在这种模式下,每次启动活动,都会创建一个新的活动实例压入返回栈中,并不在意是否有该活动的其他实例已存在。
如下所示,使用intent,点击界面时跳转。
也就是活动1跳转到活动2跳转活动3再跳转活动1,那么standard模式下会将这些活动实例依次压入返回栈中(活动1的实例存在两个)。
此时点击Back键,会销毁最上面的活动,下面的一个活动就会重新显示出来。具体流程如下所示:
活动1 > 活动2 > 活动3> 活动1(点击返回键) > 活动3(点击返回键) > 活动2(点击返回键)> 活动1
注: >为跳转的意思
SingleTask
在这种模式下如果返回栈中已存在,就会将其上面的活动全部出栈,使其重新显示在栈顶。
<activity android:name=".FirstActivity"
android:launchMode="singleTask">
注意:比如活动1,设置了其活动启动方式为singleTask。所以当从页面3跳转到页面1时,它会去返回栈中寻找是否已存在活动1,结果是存在,这时,就会把压在活动1上面的活动全部出栈。
此时点击返回键,由于压在界面1上的活动都已出栈了。所以会直接退出应用。
活动1 > 活动2 > 活动3 > 活动1 (点击返回键)> 退出应用
也就是说,此时的活动1其实是复用,所以它的onCreate方法并不会执行。虽然他用了intent跳转,但是此时的活动1只是相当于从不可见状态恢复可见,只会执行onRestart方法。
活动的启动模式详解
Intent的Flag详解
FLAG_GRANT_READ_URI_PERMISSION
如果设置了,Intent的接受者将被准许执行read操作(Intent 携带的URI数据和任何Clipdata中特定的URIs数据)的权限。
FLAG_GRANT_WRITE_URI_PERMISSION
如果设置了,Intent的接受者将被准许执行write操作(Intent 携带的URI数据和任何Clipdata中特定的URIs数据)的权限。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
当结合使用 flag_grant_read_uri_permission 和/或 flag_grant_write_uri_permission,URI权限授予可以坚持在设备重新启动直到明确撤销 用revokeuripermission(URI,int)。
FLAG_GRANT_PREFIX_URI_PERMISSION
当结合使用 flag_grant_read_uri_permission 和/或 flag_grant_write_uri_permission,URI权限授予适用于任何前缀匹配不同于原始的授予的URI。
FLAG_DEBUG_LOG_RESOLUTION
使能够使用调试功能的flag。设置之后,日志信息将在intent处理过程被输出,为了告诉你最后的解决列表被发现已创建。
FLAG_FROM_BACKGROUND
可以由调用者设置,以指示此意图来自后台操作,而不是来自直接用户交互.。
FLAG_ACTIVITY_BROUGHT_TO_FRONT
这个flag不能正常地被应用程序代码设置,而是系统为你设置由于在 launchMode 设置为singleTask模式
FLAG_ACTIVITY_CLEAR_TASK
如果通过 Context.startactivity()去设置/启动一个Intent,这个flag将导致任何存在的task,将与活动开始前清除的活动相关联.
FLAG_ACTIVITY_CLEAR_TOP
如果已设置,并且正在启动的活动已经在当前任务(backstack)中运行,那么,而不是启动该活动的新实例,而且它上面的所有其他活动都将被关闭,而这个意图将作为一个新的意图传递到(现在的顶部)旧活动中.。
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
这个常数是在API级别21废弃掉。在API 21执用 flag_activity_new_document 替代
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
如果设置,新活动不保存在最近启动的活动列表中。
FLAG_ACTIVITY_FORWARD_RESULT
如果设置这个intent是被用来从一个现有的acitivity启动到新的acitivity,现有activity的回复目标将被转移到新的activity。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
这个flag不能正常地被应用程序代码设置,而是系统为你设置,如果这个活动正在展开的历史堆栈(长按 Home键)。
FLAG_ACTIVITY_MULTIPLE_TASK
此标志用来创建一个新的task和启动一个活动到此任务
FLAG_ACTIVITY_NEW_DOCUMENT
此标志用于将文档打开到一个新的任务中,该任务源于intent启动的活动。
FLAG_ACTIVITY_NEW_TASK
设置此标志使activity将成为此历史堆栈上新任务的开始
FLAG_ACTIVITY_NO_ANIMATION
如果通过 Context.startactivity()去设置/启动一个Intent,这个标志将阻止系统执行一个活动去下一个活动的过渡动画。
FLAG_ACTIVITY_NO_HISTORY
设置此标志activity将不添加到回退栈(backStack)
FLAG_ACTIVITY_NO_USER_ACTION
设置此标志,将阻止onuserleavehint()正常回调发生在当前最前的活动,在它被停下来作为新启动活动被带到前面。
FLAG_ACTIVITY_PREVIOUS_IS_TOP
如果设置并使用此意图从现有的一个activity a启动到新activity b,新avitivity b将不会被视为栈顶而是activity a,而是决定是否新意图传递到顶部而不是启动新的活动。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
设置此标志使这个活动要么开始在一个新的任务或带到现有的任务的顶部,那么它将被启动作为任务的前门。
FLAG_ACTIVITY_REORDER_TO_FRONT
如果在通过 Context.startactivity()去设置/启动一个Intent,如果需要启动的activity已经运行,此标志使被启动的活动被带到任务的历史堆栈的前面.。
FLAG_ACTIVITY_SINGLE_TOP
如果设置,activity将不会被启动如果其正在backstack的栈顶
FLAG_ACTIVITY_TASK_ON_HOME
如果在通过 Context.startactivity()去设置/启动一个Intent,此flag将使新启动任务置于当前活动任务的顶部(如果只有一个task时)。
FLAG_RECEIVER_REGISTERED_ONLY
如果设置,当发送一个广播只有注册接收器将被调用,没有BroadcastReceiver组件将被启动。
Java基础不好的小水怪,正在学习。有错请指出,一起加油。