三、Activity的启动模式

启动模式是Android用来控制Activity活动栈行为的一种标志

作用:

  1. 对栈的操作能够不按顺序处理
  2. 多次启动同一个Activity,系统会创建多个实例,白白浪费内存

有两种方式:清单中launchMode和Intent对象调用setFlags方法

区别

优先级:动态指定方式比清单的优先级高
限定范围:清单配置无法指定FLAG_ACTIVITY_CLEAR_TOP 标识,动态指定无法指定singleInstance 模式
setFlags可以在不同时候对同一个Activity运用不同的启动模式

注:setFlags当前设置当前生效,也只会在当前生效,过后还是按照清单的配置走

四种启动模式

1、standard:默认标准模式:
每次启动一个Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在
2、singleTop:栈顶复用模式:
须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;
若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样
生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。
可是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)

    @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
initData(); //在这getIntent().getStringExtra()获取值
initView(); //在这重新设置新的ui
}
注意:需要重新setIntent(intent),否则还是获取的是老的数据  

3、singleTask:栈内复用模式
若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。
生命周期:同SingleTop 模式中的情况一同样。仅仅会调用一次Activity中的 onNewIntent方法
4、singleInstance:单实例模式
此模式的Activity仅仅能单独位于一个任务栈中
这个经常使用于系统中的应用,比如Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到

Activity的常见Flags

1、FLAG_ACTIVITY_NEW_TASK
作用是为Activity指定 “SingleTask”启动模式。跟在AndroidMainfest.xml指定效果同样。

2、FLAG_ACTIVITY_SINGLE_TOP
作用是为Activity指定 “SingleTop”启动模式,跟在AndroidMainfest.xml指定效果同样。

3、FLAG_ACTIVITY_CLEAN_TOP
作用是销毁目标Activity和它之上的所有Activity,重新创建目标Activity

4、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有此标记位的Activity不会出如今历史Activity的列表中,使用场景:当某些情况下我们不希望用户通过历史列表回到Activity时,此标记位便体现了它的效果。
它等同于在xml中指定Activity的属性:android:excludeFromRecents=”true”

浅谈下为什么有时在启动Activity时需要加FLAG_ACTIVITY_NEW_TASK

报这个错是在Activity上下文之外启动的
在Receiver中使用context的startActivity方法的话,这个方法源码在执行真正的调用之前会检查一下有没有设置这个FLAG_ACTIVITY_NEW_TASK的标志,没有设置的话就报上面所说的那个异常。
那么为什么我们在Activity中直接startActivity方法就不会报这个异常呢?这是因为Activity类在自己的实现中已经覆盖了父类的startActivity方法去除了这个检查

FLAG_ACTIVITY_NEW_TASK的意义:

一般来说当我们从launcher中启动一个应用进入到ActivityA中,系统会为这个应用生成一个新任务堆栈并置于前台,ActivityA被放入栈底,之后从ActivityA启动另一个ActivityB,如果不设置什么附加属性,ActivityB默认也放到和ActivityA这个堆栈中,这样当你按返回时,B出栈,A呈现出来了,这个应该很好理解。
那现在假如ActivityA启动一个Service或者发一个广播,这都是后台的活,和我们的任务栈没有关系,现在假如我们在广播中需要启动一个Activity,当然需要为这个Activity指定或分配一个任务栈,FLAG_ACTIVITY_NEW_TASK的意义就是这个

四种启动模式的生命周期

standard:
第一次进入:onCreate onStart
在栈顶再次进入: onCreate onStart
不在栈顶再次进入:onCreate onStart

singleTop:
第一次进入:onCreate onStart
在栈顶再次进入:onNewIntent
不在栈顶再次进入:onCreate onStart
按home键 再次进入:onRestart onStart

singleTask:
第一次进入:onCreate onStart
在栈顶再次进入:onNewIntent
不在栈顶再次进入:onNewIntent onRestart onStart
按home键再次进入:onRestart onStart

singleInstance:
第一次进入:onCreate onStart
在栈顶再次进入: onNewIntent
不在栈顶再次进入:onNewIntent onRestart onStart
按home键再次进入:onRestart onStart

参考文档:https://blog.csdn.net/elisonx/article/details/80397519

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注