Android 启动模式及常用的Intent的Flag
LaunchMode
在声明Activity的xml中指定 android:launchMode="xxx"
standard
标准模式。这是系统默认的模式,每次启动Activity都会重新创建一个新的Activity实例,也就是onCreate,onStart,onResume流程走一遍,并且一个任务栈里允许存在多个实例。
当我们使用ApplicationContext去启动Activity的时候,因为默认是standard模式会报错:
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
因为standard 模式默认启动的Activity会和启动它的Activity在同一任务栈,而由于ApplicationContext非Activity的Context,并没有所谓的任务栈,所以提示我们需要使用FLAG_ACTIVITY_NEW_TASK来新建一个任务栈并把启动的Activity放进去。
singleTop
栈顶复用模式。在同一个任务栈中栈顶如果有此Activity的实例,那么不会重新创建一个新实例,而是调用此Activity的onNewIntent,此时onCreate、onStart不会被调用。但如果此Activity在同一个任务栈但不在栈顶或之前用standard模式启动的,就会重新创建。
如ADBCD(第一个D不在栈顶则重新创建),ABCDD(第一个D为standard模式启动也会重新创建)。
singleTask
栈内复用模式。在同一个任务栈(注意:不一定是栈顶了)中如果有此Activity的实例,那么不会重新创建一个新实例,而是调用此Activity的onNewIntent,此时onCreate、onStart不会被调用。并且自带FLAG_ACTIVITY_CLEAR_TOP效果。
同一个栈内。如ADBC(要启动D,则把D挪到栈顶,BC由于clearTop而被移除栈,剩下AD)。
如果D指定栈为S2,android:taskAffinity="S2",而启动它的Activity栈为S1,则先创建S2栈然后再new D放到S2中。
singleInstance
单例模式。这是一种加强的singleTask模式。除了singleTask模式所有特性外,它只能单独在一个任务栈中,跟其他Activity不能同时存在一个任务栈,整个Application也只有一个实例。
Intent的Flag
我们在代码里面通过Intent启动Activity的时候可以添加flag,如 :
intent.addFlags(Intent.FLAG_ACTIVITY_XXX);
FLAG_ACTIVITY_BROUGHT_TO_FRONT
这个标志一般不是由程序代码设置的,如在launchMode中设置singleTask模式时系统帮你设定。
FLAG_ACTIVITY_CLEAR_TASK
此Activity将变成一个新Task中新的最底端的Activity,所有的之前此Activity实例和包含该实例的Task都会被关闭,这个标识仅仅和FLAG_ACTIVITY_NEW_TASK联合起来才能使用。
FLAG_ACTIVITY_NEW_TASK
与launchMode="singleTask"一样的效果。
FLAG_ACTIVITY_CLEAR_TOP
清除包含此Activity的Task中位于该Activity实例之上的其他Activity实例。这种行为的 launchMode 属性没有对应的值,只能通过代码设置。
单独使用的情况:ABCD 启动 B ,会销毁B和B以上的实例 变成 AB ,B 重新执行onCreate -> onStart
配合FLAG_ACTIVITY_SINGLE_TOP使用,则 B 不会销毁只销毁B以上实例,然后B 执行onNewIntent -> onStart
配合FLAG_ACTIVITY_NEW_TASK则是singleTask效果
FLAG_ACTIVITY_SINGLE_TOP
与launchMode="singleTop"一样的效果。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
设置了的话该Activity则不出现在最近使用的列表中。
FLAG_ACTIVITY_FORWARD_RESULT
如果A需要onActivityResult中获取返回结果,startActivityForResult B,而B只是过渡页,启动C之后就finish掉了,需要在 C 中setResult返回给A就可以用到这个标志。
A -> B -> XXXXX(无论多少个过渡页) 设置 FLAG_ACTIVITY_FORWARD_RESULT 来启动 C ,之后该XXX过渡页finish - > C ,那么C的结果返回给A
FLAG_ACTIVITY_NO_HISTORY
如果设置,新的Activity将不再历史stack中保留。用户一离开它,这个Activity就关闭了。
例如A启动B的时候,给B设置了FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,那么:
A -> B -> C ,启动C 就算 B没有自行finish ,也会变为 AC
FLAG_ACTIVITY_NO_ANIMATION
启动的时候不执行动画。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
当用户点击Home,从历史中选择该Activity,系统会自动加上这个Flag。
FLAG_ACTIVITY_NO_USER_ACTION
在onPause()之前会调用onUserLeaving( )方法,如果使用了该标识,说明目标Activity不和用户交互,所以也就不需要回调onUserLeaving( )方法。
FLAG_ACTIVITY_REORDER_TO_FRONT
如果设置这个标记,新启动的Activity将会被放到它所属task的最前面
例如,假如有一个Task包含4个Activity:A,B,C,D.如果D通过调用startActivity( )来启动B,如果使用了这个标记,B将会排在这个task的最上面,也即现在的顺序变成了A,C,D,B。
如果使用了FLAG_ACTIVITY_CLEAR_TOP,这个标记将会被忽略。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
如果设置该属性,并且这个Activity在一个新的Task中正在被启动或者被带到一个已经存在的Task的顶部,这时这个Task会被重置(即该Task中之前的Activity会被关闭),该Activity成为栈底第一个Activity。
FLAG_ACTIVITY_TASK_ON_HOME
把当前新启动的任务置于Home任务之上,也就是按back键从这个任务返回的时候会回到Home,即使这个不是他们最后看见的Activity。
注意这个标记必须和FLAG_ACTIVITY_NEW_TASK加上android:taskAffinity一起使用。
FLAG_DEBUG_LOG_RESOLUTION
用来调试,当设置这个标志的时候,在解析这个intent的时候,将会打出打印信息(queryIntent函数)。
FLAG_INCLUDE_STOPPED_PACKAGES 和 FLAG_DEBUG_LOG_RESOLUTION
从Android 3.1开始,给Intent定义了两个新的Flag,分别为FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES,用来控制Intent是否要对处于停止状态的App起作用,顾名思义:
FLAG_INCLUDE_STOPPED_PACKAGES:表示包含未启动的App
FLAG_EXCLUDE_STOPPED_PACKAGES:表示不包含未启动的App
值得注意的是,Android 3.1开始,系统向所有Intent的广播添加了FLAG_EXCLUDE_STOPPED_PACKAGES标志。这样做是为了防止广播无意或不必要地开启未启动App的后台服务。如果要强制调起未启动的App,后台服务或应用程序可以通过向广播Intent添加FLAG_INCLUDE_STOPPED_PACKAGES标志来唤醒。
FLAG_FROM_BACKGROUND
Intent不光可以在Acitivity里面start,还可以从service里面启动,这个参数就表示这个Intent是从后台服务发起的。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
区别于 FLAG_GRANT_READ_URI_PERMISSION 跟 FLAG_GRANT_WRITE_URI_PERMISSION, URI权限会持久存在即使重启,直到明确的用 revokeUriPermission(Uri, int) 撤销。 这个flag只提供可能持久授权。但是接收的应用必须调用ContentResolver的takePersistableUriPermission(Uri, int)方法实现 。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
Uri 权限授予任何原始授权URI前缀匹配的URI。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
结合FLAG_GRANT_READ_URI_PERMISSION 和 FLAG_GRANT_WRITE_URI_PERMISSION 使用。
Uri 权限授予任何原始授权URI前缀匹配的URI。如果没有这个标志则必须精确匹配Uri了。
FLAG_GRANT_READ_URI_PERMISSION 和 FLAG_GRANT_WRITE_URI_PERMISSION
临时访问读权限和写权限 。Intent的接受者将被授予 INTENT 数据 uri 或者 在ClipData 上的读/写权限。
FLAG_RECEIVER_FOREGROUND
当发送广播时,允许其接受者 在前台运行的拥有更高的优先级,更短的超时间隔。
FLAG_RECEIVER_NO_ABORT
如果是有序广播,不要允许接收者中断广播播。
FLAG_RECEIVER_REGISTERED_ONLY
设置之后就不能通过xml来注册监听这个广播了,必须动态注册。
很多毒病程序为了证保自己被止终后可以再次行运,都会在xml中册注一些系统广播,妄图利用这些系统高频广播来实现自动启。
比如在老版本的android系统中,毒病程序可以通过监听TIME_TICK来动启自己的service后台行运,做一些秘隐的作工,而且就算自己被kill失落了,也能很快重新动启。
而一旦这些系统广播加了flag FLAG_RECEIVER_REGISTERED_ONLY,这些毒病程序就没辙了。例如系统的TIME_TICK广播,由AlarmManagerService发送,我们看源码可以看到
mTimeTickSender = PendingIntent.getBroadcast(context, 0,
new Intent(Intent.ACTION_TIME_TICK).addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0);
这样就不能监听ACTION_TIME_TICK来自启动了。
FLAG_RECEIVER_REPLACE_PENDING
这个Flag 将会将之前的Intent 替代掉。加了这个Flag,在发送一系列的这样的Intent 之后,中间有些Intent 有可能在你还没有来得及处理的时候,就被替代掉了。
FLAG_ACTIVITY_NEW_DOCUMENT(原FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
可以跟FLAG_ACTIVITY_MULTIPLE_TASK结合使用,当只用自己的时候相当于Manifast中 android.R.attr.documentLaunchMode="intoExisting",当跟FLAG_ACTIVITY_MULTIPLE_TASK 结合使用相当于 Manifast中android.R.attr.documentLaunchMode="always"。
FLAG_ACTIVITY_RETAIN_IN_RECENTS
默认情况下通过FLAG_ACTIVITY_NEW_DOCUMENT启动的Activity在关闭之后,Task中的记录会相对应的删除。如果为了能够重新启动这个Activity你想保留它,就可以使用者个flag,最近的记录将会保留在接口中以便用户去重新启动。接受该Flag的Activity可以使用autoRemoveFromRecents去复写这个request或者调用Activity.finishAndRemoveTask( )方法。
FLAG_ACTIVITY_MULTIPLE_TASK
这个标识用来创建一个新的task栈,并且在里面启动新的activity(所有情况,不管系统中存在不存在该activity实例),经常和FLAG_ACTIVITY_NEW_DOCUMENT或者FLAG_ACTIVITY_NEW_TASK一起使用。这上面两种使用场景下,如果没有带上FLAG_ACTIVITY_MULTIPLE_TASK标识,他们都会使系统搜索存在的task栈,去寻找匹配intent的一个activity,如果没有找到就会去新建一个task栈;但是当和FLAG_ACTIVITY_MULTIPLE_TASK一起使用的时候,这两种场景都会跳过搜索这步操作无条件的创建一个新的task。和FLAG_ACTIVITY_NEW_TASK一起使用需要注意,尽量不要使用该组合除非你完成了自己的顶部应用启动器,他们的组合使用会禁用已经存在的task栈回到前台的功能。
taskAffinity 和 allowTaskReparenting
taskAffinity用于指定当前Activity所关联的Task,allowTaskReparenting用于配置是否允许该Activity可以更换从属Task,通常情况二者连在一起使用,用于实现把一个应用程序的Activity移到另一个应用程序的Task中。
allowTaskReparenting用来标记Activity能否从启动的Task移动到taskAffinity指定的Task,默认是继承至application中的allowTaskReparenting=false,如果为true,则表示可以更换;false表示不可以。
例如在A应用中启动了B应用的Activity,如果设置allowTaskReparenting=true,则Activity允许从A的Task移动到B的Task。但如果A被启动之后,Activity就会回到A的Task中。
原文链接:http://www.jianshu.com/p/7f1c9fac2af2
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
Android 启动模式及常用的Intent的Flag的更多相关文章
- android 启动模式介绍
Android启动模式 (1)Task:与Android系统是个多任务的系统中的任务是不同的.后者更倾向于多进程和多线程来说的,而这里的任务与application(应用程序)和activity(活动 ...
- Android 启动模式--任务(Task)--桟 的误区
Android 启动模式--任务(Task)--桟 的误区 写这篇文章是因为前几天的一次面试,面试官说SingleInstance模式会新建一个桟,而SingleTask不会.首先不说这个对不对(非要 ...
- Android启动模式(三种)
1,标准启动模式 通过任务栈,每点一次button,将每一个实例都压入,然后点返回键时候,就弹出之前压入的实例. 每一次的地址都是不同的 测试代码:通过创建一个button和textView来显示本身 ...
- android启动模式2
Android中的启动模式(下) 在这篇文章中,我会继续跟大家分享有关于Android中启动模式的相关知识.当然,如果对这个启动模式还不完全了解或者没有听过的话,可以先看看我之前写的有关于这个知识点的 ...
- 我所理解的Android 启动模式
首先,这是从 一个开源网站转载的,觉得写得不错,对我们之前理解的activity的启动模式是一个新的理解方式,并给出实际的应用场景. 任务栈是什么 任务栈Task,是一种用来放置Activity实例的 ...
- "standard,singleTop,singleTask,singleInstance"-Android启动模式
安卓有4种启动模式,下面我们就进行详细的讲解 用栈的思维去理解,就能理解这些启动模式的本质了 先设置两个页面: A(为测试对象),B两个页面,两个页面都有跳至对方的按钮 一.标准模式(standard ...
- android启动模式对于体验的影响
说到Android的启动模式.懂Android的人肯定都懂. 通过设置启动模式我们不仅能够节省内存的使用.还能达到更好的体验,比方我们打开一个应用,点击home键回到主界面的时候程序是没有被kill掉 ...
- Android启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- Android启动模式launchMode
在Android里,有4种Activity的启动模式并分别介绍下: standard singleTop singleTask singleInstance AndroidManifest.xml配置 ...
随机推荐
- @font-face 的用法
现在很多设计用的字体都是五花八门的.我们切图又不能很好的让搜索爬虫搜索.就会使用@font-face方法: @Font-face目前浏览器的兼容性: Webkit/Safari(3.2+):TrueT ...
- Spark External Datasets
Spark能够从任何支持Hadoop的存储源来创建RDD,包括本地的文件系统,HDFS,Cassandra,Hbase,Amazon S3等.Spark支持textFile.SequenceFiles ...
- .net core 学习笔记(1)-分页控件的使用
最近有个小项目,用.net core开发练练手,碰到的第一个问题就是分页控件的问题,自己写太费时间,上网查了下,发现有人已经封装好了的,就拿过来用了,分页控件github:https://github ...
- Java 图片压缩
package com.wuyu.util; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.Buff ...
- 学习linux/unix编程方法的建议(转)
假设你是计算机科班出身,计算机系的基本课程如数据结构.操作系统.体系结构.编译原理.计算机网络你全修过 我想大概可以分为4个阶段,水平从低到高从安装使用=>linux常用命令=>linux ...
- 如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可
如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可(项目需要使用QuartzCore框架).而若要指定某几个角(小于4)为圆角而别的不变时 ...
- ocx控件 编译成C#调用的dll 方法 转
打开VS命令提示行 1.注册ActiveX控件(带上 VCbox.ocx的路径) regsvr32 VCbox.ocx 2.编译OCX文件 aximp VCbox.ocx 生成两个dll文件,项 ...
- C#中隐藏(new)、方法重写(override)、重载(overload)的区别
转自:http://www.cnblogs.com/glife/archive/2009/12/28/1633947.html 重载.重写和隐藏的定义: 重载:public string ToStri ...
- 电脑重装BIOS设置中文翻译
- cs231n笔记:线性分类器
cs231n线性分类器学习笔记,非完全翻译,根据自己的学习情况总结出的内容: 线性分类 本节介绍线性分类器,该方法可以自然延伸到神经网络和卷积神经网络中,这类方法主要有两部分组成,一个是评分函数(sc ...