你应该知道Activity一切
1.SingleTop
栈顶复用,当Activity位于栈顶的时候在启动该Activity,那么这个Activity不会被重新创建,会调用onNewIntent(Intent intent)
,如果不在栈顶,则跟默认的启动模式一样,会重新创建。
2.SingleTask
栈内复用,当Activity已经创建过,且存在栈内了,当再启动该Activity,那么会把该Activity上面所有Activity都退出栈,并调用onNewIntent(Intent intent)
方法
3.SingleInstance
新的任务栈,当以这种模式启动,会创建一个新的ActivityTask存放这个Activity
4.Standard
默认模式,你只要启动 我就给你创建,并压入栈内。
虽然
SingleTask,SingleTop
都可能会复用Activity,但是注意的是SingleTop
是栈顶复用。
以下摘自intent源码
/**
* If set, the new activity is not kept in the history stack. As soon as
* the user navigates away from it, the activity is finished. This may also
* be set with the {@link android.R.styleable#AndroidManifestActivity_noHistory
* noHistory} attribute.
*
* <p>If set, {@link android.app.Activity#onActivityResult onActivityResult()}
* is never invoked when the current activity starts a new activity which
* sets a result and finishes.
*/
当标记该FLAG后启动的activity是不会在存在ActivityTask ,例如A启动B,B启动C,C finish()后看到的界面是A,这个时候B也同时被 finish()了
singleTop设置后形势与启动模式SingleTop一致
标志启动在一个新的Task中。当与FLAG_ACTIVITY_CLEAR_TOP一起用,与启动模式SingleTask一致FLAG_ACTIVITY_MULTIPLE_TASK, 消除FLAG_ACTIVITY_NEW_TASK这个标志位的FLAG_ACTIVITY_CLEAR_TOP,清除这个activity栈顶的所有activity
/**
* If set and this intent is being used to launch a new activity from an
* existing one, then the reply target of the existing activity will be
* transfered to the new activity. This way the new activity can call
* {@link android.app.Activity#setResult} and have that result sent back to
* the reply target of the original activity.
*/
这个标志位用于A启动B,B启动C,C要把result返回给A,这个时候B启动C的时候带上这个标志位就可以了。这个时候C finish()的时候必须带上 setResult 方法,否则系统会抛出异常。
即 A---> B --->C,若B启动C时用了这个标志位,那在启动时B并不会被当作栈顶的Activity,而是用A做栈顶来启动C。
此过程中B充当一个跳转页面。典型的场景是在应用选择页面,
如果在文本中点击一个网址要跳转到浏览器,而系统中又装了不止一个浏览器应用,
此时会弹出应用选择页面。在应用选择页面选择某一款浏览器启动时,就会用到这个Flag。
然后应用选择页面将自己finish,以保证从浏览器返回时不会在回到选择页面。
经常与FLAG_ACTIVITY_FORWARD_RESULT 一起使用。
以上这些要么是系统用的,要么是不常用,不做解释了
禁止activity调用onUserLeaveHint()。onUserLeaveHint()作为activity周期的一部分,它在activity因为用户要跳转到别的activity而退到background时使用。比如,在用户按下Home键(用户的操作),它将被调用。比如有电话进来(不属于用户的操作),它就不会被调用。注意:通过调用finish()时该activity销毁时不会调用该函数。
/**
* If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
* this flag will cause the launched activity to be brought to the front of its
* task's history stack if it is already running.
*
* <p>For example, consider a task consisting of four activities: A, B, C, D.
* If D calls startActivity() with an Intent that resolves to the component
* of activity B, then B will be brought to the front of the history stack,
* with this resulting order: A, C, D, B.
*
* This flag will be ignored if {@link #FLAG_ACTIVITY_CLEAR_TOP} is also
* specified.
*/
注释说的很清楚 就是把要启动的放到最栈顶 但是与FLAG_ACTIVITY_CLEAR_TOP相冲突
启动不带动画
全部清空栈
该flag启动的activity,点击返回键会回到launcher.需要与
FLAG_ACTIVITY_NEW_TASK
一起使用,并且FLAG_ACTIVITY_NEW_TASK
模式生效(参考该属性)后,该flag才会起作用. FLAG_ACTIVITY_RETAIN_IN_RECENTS,与activity设置autoRemoveFromRecents = false属性效果一样.是指当前activity销毁后,是否还在概览屏幕中显示.(5.0之后生效)
以上参考Intent源码注释,《Android开发艺术探索》以及 这篇文章
启动Activity有隐式和显式2中方式,这里首先简单说一下显式启动
Intent intent = new Intent();
intent.setClass(@NonNull Context packageContext, @NonNull Class<?> cls)
context.startActivity(intent);
这里是简单的调用intent启动activity,一般是不会出错,但是如果启动系统的activity,容易启动失败,这个时候 就需要intent.resolveActivity()
来确定这个activity是否能够安全启动,当不反回为null的时候就可以安全启动。
resolveActivity 的源码如下
核心方法就是这个
ResolveInfo info = pm.resolveActivity(
this, PackageManager.MATCH_DEFAULT_ONLY);
会去遍历满足条件的activity的返回回来,
PackageManager.MATCH_DEFAULT_ONLY
这个的作用就是只返回Action和Category满足的activity。
隐式启动需要在activity的标签内设置Intent-filter来过滤对应的activity。