Activity启动模式
都说2019年正式进入互联网的寒冬期,今年将是之前最艰难的一年,也将会是之后最容易的一年,说的我心里好慌,那又能怎样,只能顶着寒冬的凌冽东风匍匐前进了,只能不断的积累来巩固自己的知识脂肪抵御这寒风…
一、Activity四大发动机(启动模式)
各位看官们,如果您是有一定的工作经验的我相信您对我这段标题引言肯定是内心大笑三声,因为Activity的启动模式只要是面试一般都会问到,或者在笔试中基础中基础题中出现个过这个问题。记得第一次面试还万分紧张的回答了这个问题。那么我就再次紧张的介绍一下吧!
在此之前我们先简单讲一下Back Stack栈,android会按照“先进后出”的原则将启动的Activity按照一定顺序进行压栈出栈。
首先我们来看一下配置清单中Activity的配置:
<activity android:name=".ui.MainActivity" />
由于我们此篇文章只讲述启动模式,所以其他相关配置直接无视,这个是我们最简单个一个配置,若我们用as创建Activity时清单文件里默认就会类似如此简单的配置信息,没错只有一个Activity的声明,不是说好了的启动模式吗?where?那就请我们的默认启动模式登场:
- Standard模式:(在未声明Activity的启动模式时,默认为standard模式)
若由有Activity(简称为A)启动模式为standard模式,无论当前是否创建过A,每次我们启动一个A都会创建一个新的实例压入到我们的栈中.
生命周期:此模式下每创建一个Activity,都会调用它的onCreate()、onStart()、onResume()方法
以下为两种情况:
- SingleTop 栈顶复用模式:
此种模式分为两种情形:
第一种为:当前栈内Activity为a-b-c,a为栈底的Activity而c为栈顶Activity,此时在c中重新启动
一个a,由于a不在栈顶,所以会重新创建一个a并压入栈中,此时站内为(a-b-c-a)。
生命周期:此情况下同standard模式
第二种为:当前栈内Activity为b-c-a,a为栈顶的Activity而b为栈底Activity,此时在a中重新启动
一个a,由于a在栈顶,所以并不会重新创建一个a,而只是复用a,此时栈内为(b-c-a)。
生命周期:此情况下,创建时,不会调用生命周期方法onCreate()、onStart(),由于是复用没有发生改变,它会调用onNewIntent()方法(此方法在正常的创建下不回被调用,我们可以在此方法内更新数据和UI)
- SingleTask栈内复用模式
若需要创建的Activity此时处于栈中,则不会创建新的Activity,而是将存在栈中Activity上的其他Activity全部销毁,使他变为栈顶。
- SingleInstance单例模式
此模式只会创建一个Activity实例,并且创建一个新的栈,此栈有且只有这一个activity,无论此栈中本身重新创建此activity还是其他栈中activity创建此activity,最终跳转的都是此栈中这个实例,不会重新创建仍然是复用这个。
⚠️:以上只要是当前activity没有被创建即第一次创建,其生命周期方法正常调用:
onStart()->onCreate()->onResume()->…
对于此模式还有一些扩展,这篇文章是其他博主编写的大家有兴趣可以看一下(是兄弟来点我)。
二、启动模式配置方式
- 在配置文件中,配置Activity的启动模式
<activity android:name=".Main2Activity" android:launchMode="启动模式"></activity>
1、standard
2、singleTop
3、singleTask
4、singleInstance
- 通过Intent意图启动Activity并配置其启动模式
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
以上两种方式都能配置Activity的启动模式,如果两种方式都使用了,将会以配置文件为主。
针对于第二种方式来讲,并不是四种模式都有对应的flag。我们来简单看一下一些flag。
- FLAG_ACTIVITY_NEW_TASK
这个标记位就是为Activity指定singleTask启动模式。 - FLAG_ACTIVITY_SINGLE_TOP
这个标记位就是为Activity指定singleTop启动模式。 - FLAG_ACTIVITY_CLEAR_TOP
具有此标记位的Activity,当它启动时,在同一个任务栈中,所有位于它上面的Activity都要出栈。 - FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
和配置文件属性android:excludeFromRecents="true"一致,主要功能是隐藏应用,在 Recent screens中不显示。
对于android:excludeFromRecents="true"
官方文档翻译: 是否应将该 Activity 启动的任务排除在最近使用的应用列表(即概览屏幕)之外。 也就是说,当该 Activity 是新任务的根 Activity 时,此属性确定任务是否应出现在最近使用的应用列表中。 如果应将任务排除在列表之外,请设置“true”;如果应将其包括在内,则设置“false”。 默认值为“false”。
也就是说我们要想这个属性生效,就必须设置在Task的根Activity上,如果不是根Activity上,那就失效了。
若当前的根activity正在运行处于获取焦点的状态,此时若查看 Recent screens,是可以查看到当前应用的,若是通过home按键回到桌面,再查看 Recent screens此时又查看不到应用了,成功的隐藏了,此时属性又生效了。
三、启动模式对应的一些应用场景
- SingleTop模式
singleTop对于处于栈顶且类型一致的信息展示,减少重复创建浪费的资源。
eg:新闻app收到多个新闻推送,每次点开一个推送Dialog都创建一个页面就很浪费资源了,而且跳转不销毁的话,返回很费劲,这时使用SingleTop模式就大大提高我们效率节省资源。
- SingleTask栈内复用模式
若只希望当前Task只存在一个当前类型的Activity实例,在回到当前Activity时,对于在其之上的Activity进行销毁没有多大的损失或者没有影响,此时使用更合适。
eg:app的主页使用此模式,返回到主页时就把其他的activity销毁了。若不使用此模式可能在返回时多次看到我们的app主页,用户体验极差。
- SingleInstance单例模式
对于整个系统只有这一个的情形,比如说:来电呼叫等。
对于Android的启动模式暂时介绍到这里,关于Intent的flag后续找个时间专门做个介绍,感谢大家对本篇文章给出自己的见解,若有不正确的地方还请各位客观提出,感谢!!!