Activity的启动模式
任务栈
- android任务栈又称为Task,它是一个栈结构,具有后进先出的特性,用于存放我们的Activity组件。
 - 我们每次打开一个新的Activity或者退出当前Activity都会在一个称为任务栈的结构中添加或者减少一个Activity组件,因此一个任务栈包含了一个activity的集合, android系统可以通过Task有序地管理每个activity,并决定哪个Activity与用户进行交互:只有在任务栈栈顶的activity才可以跟用户进行交互。
 - 在我们退出应用程序时,必须把所有的任务栈中所有的activity清除出栈时,任务栈才会被销毁。当然任务栈也可以移动到后台, 并且保留了每一个activity的状态. 可以有序的给用户列出它们的任务, 同时也不会丢失Activity的状态信息。
 - 需要注意的是,一个App中可能不止一个任务栈,某些特殊情况下,单独一个Actvity可以独享一个任务栈。还有一点就是一个Task中的Actvity可以来自不同的App,同一个App的Activity也可能不在一个Task中。
 
任务栈信息可以通过 adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'指令来查看 栈信息.
四种启动模式
-  
standard: 默认的启动模式,每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在.Activity的启动三回调(onCreate()->onStart()->onResume())都会执行。 如在一个任务栈中,连续调用3次MainActivity,那么任务占中就会存在三个MainActivity记录. -  
singTop: 栈顶复用模式. 当准备启动的Activity已经位于任务栈栈顶时,不会再创建一个新的Activity,此时栈顶Activity的onNewIntent方法会被回调.当准备启动的Activity不在任务栈的栈顶存在时,(无论在栈中存在或者在非栈顶),都会重新创建 Activity. -  
singleInstance: 单实例模式. 系统为声明为singleInstance模式的Activity,单独使用一个任务栈存放.即一个Activity对应一个任务栈,且一个Activity最多存在一个实例. 后续请求都不会创建Activity,只会调用其onNewIntent回调. -  
singleTask: 栈内复用模式. 在这种模式下,如果Activity已经存在某个任务栈中,多起启动该Activity都不会被重建,只会调用其onNewIntent方法,并将其移动到栈顶位置. 
 singleTask模式
 
 当启动Activity时,如果Activity已经存在于 任务栈的非栈顶位置, 任务栈中该Activity之上的 Activity将会被全部移除,只保留该Activity以及其一下的Activity.
 即 具有 clearTop的效果.
当启动Activity的任务栈B在后台时,此时任务栈A中的Activity启动了,任务栈B中的 singleTask模式的Activity,则任务B栈的 被启动Activity会clearTop到栈顶位置,然后整个任务栈B重返至前台.
引用 官方示例来说明 :
   前台栈中的栈顶Activity2 启动了 位于后台栈的 ActivityY,此时 后台栈中的 ActivityY和ActivityX 都会被移动至前台栈中,回退两次才能回到 Activity2.
 taskAffinity属性
 
 taskAffinity是AndroidManifest中 Activity标签的属性,表示任务栈的名称.该属性可以为 Activity指定任务栈.
当Activity的启动模式为
standard,singletop模式时,taskAffinity属性将失效, Activity的将被加入到 启动它的那个Activity所在的栈.一个例外,如果在入口Activity中指定taskAffinity属性,则可以生效,因为此时应用刚启动,还没有指定的任务栈(默认的任务栈是以包名来命名的).当Activity的启动模式为
singleTask,singleInstance模式时,taskAffinity属性将在Activity被启动的时候指定任务栈,如果任务栈不存在则会创建一个taskAffinity命名的任务栈存放启动的Activity.
注意事项
如果被启动的Activity是
standard,singletop模式时, Activity将被加入到启动该Activity的任务栈中.如果被启动的Activity是
singleTask,singleInstance模式时,如果指定taskAffinity属性,则Activity被加入到 指定的栈任务栈中,未指定则被加入 以包名命名的任务栈.singleInstance模式的Activity,虽然可能被加入到名字相同的栈,但是由于其特殊性,虽然栈名相同但是不属于同一个栈.使用 application来启动Activity时, application没有所在的 任务栈.如果没有指定
FLAG_ACTIVITY_NEW_TASK,将会有如下报错.
 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
 
 Activity中的 Flags
-  
FLAG_ACTIVITY_NEW_TASK: 为Activity指定singleTask模式,相当于在xml中指定启动模式一样,除了application来启动Activity时,在xml指定singleTask是无效的,一定要在intent中指定该标志. -  
FLAG_ACTIVITY_SINGLE_TOP: 指定singleTop模式. -  
FLAG_ACTIVITY_CLEAR_TOP: 具有此标记的Activity,当它启东市,在同一个任务栈中的所有位于它上面的Activity都将被移除任务栈. -  
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: 设置了该标志,该Activity所在的任务栈将不会出现在 多任务列表(最近使用列表)中.相当于设置了android:excludeFromRecents="true". 
IntentFilter匹配规则
intent的启动有两种方式,显式调用和隐式调用.
 显示调用,我们需要明确的指定被启动的Activity的组件信息,Activity的class对象.
 隐式调用则不需要明确的知道 被调用的Activity信息,而是通过IntentFilter来指定action,category,data过滤规则配合来启动Activity.
Intent只有同时匹配了 action规则,category规则 和 data规则,才能成功的启动目标Activity.
一个 IntentFilter中可以设置多个 action,多个category和多个data.
action
intent中必须设置 action, 且能过匹配 IntentFilter中的任意一个 action就算匹配成功.
category
intent中如果含有 category,那么所有的category都能在IntentFilter中匹配上,intent中也可以不显式的设置category.
在调用 startActivity或者startActivityForResult时,系统会为intent自动添加 android.intent.category.DEFAULT标志,所以如果要想隐式的调用Activity,就必须在 IntentFilter中添加 <category android:name="android.intent.category.DEFAULT" />规则.
data
<data android:scheme="string"
      android:host="string"
      android:port="string"
      android:path="string"
      android:pathPattern="string"
      android:pathPrefix="string"
      android:mimeType="string" />
 
 data由两部分组成, URI 和 mimeType(媒体类型).
URI结构 : <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
 mimeType : image/jpeg,video/*等.
如果IntentFilter中设置了 data属性.则intent中必须设置 setData或者setType或者setDataAndType.setData或者setType方法的属性会相互覆盖.各自的方法会将对方属性设置为null.
当data中指设置了 mimeType时,可以使用 scheme为 file或content类型来设置data.
 如果需要同时指定URI和mimeType,需要使用intent的setDataAndType方法.
隐式调用,可达性检查
隐式intent启动之前,我们可以先检查 目标Activity的可达性,避免出现 android.content.ActivityNotFoundException: No Activity found to handle Intent的错误.
使用 intent的 intent.resolveActivity(packageManager) 和 packageManager的packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)来检查, 返回 null则表示找不到匹配的Activity.
参考
关注公众号
					低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 
							
								
								    上一篇
								    
								
								Material Design 实战 之第五弹 —— 下拉刷新(SwipeRefreshLayout)
本模块共有六篇文章,参考郭神的《第一行代码》,对Material Design的学习做一个详细的笔记,大家可以一起交流一下: Material Design 实战 之第一弹——Toolbar(即本文) Material Design 实战 之第二弹——滑动菜单详解&实战 Material Design 实战 之第三弹—— 悬浮按钮和可交互提示(FloatingActionButton & Snackbar & CoordinatorLayout) Material Design 实战 之第四弹 —— 卡片布局以及灵动的标题栏(CardView & AppBarLayout) Material Design 实战 之第五弹 —— 下拉刷新(SwipeRefreshLayout) Material Design 实战 之 第六弹 —— 可折叠式标题栏(CollapsingToolbarLayout) & 系统差异型的功能实现(充分利用系统状态栏空间) 引子: 文章提要与总结 SwipeRefreshLayout 1.SwipeRefreshLayou...
 - 
							
								
								    下一篇
								    
								
								一文看懂ConstraintLayout的用法
ConstraintLayout 相对于 RelativeLayout来说性能更好,布局上也更加灵活。在最新的Google Android开发文档中是推荐使用 ConstraintLayout的,下面来看看具体用法。 0x00 相对位置(Relative positioning) 这个比较简单,看图解释,假设控件B要放在控件A的右侧,可以使用 layout_constraintLeft_toRightOf属性。 <Button android:id="@+id/buttonA" ... /> <Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toRightOf="@+id/buttonA" /> 看图2可以了解控件约束属性代表的含义。 类似相对位置的约束属性有: layout_constraintLeft_toLeftOf layout_constraintLeft_toRightOf layout_constraintRight_toLeftOf layout_constraintR...
 
相关文章
文章评论
共有0条评论来说两句吧...

			
				
				
				
				
				
				
				
微信收款码
支付宝收款码