每日一道面试题(第4期)---launchMode的应用场景

零零碎碎的东西老是记不长久,仅仅学习别人的文章也只是他人咀嚼后留下的残渣。无心中发现了这个每日一道面试题,想了想若是只是简单地去思考,那么不只会收效甚微,甚至难一点的题目本身可能都懒得去想,坚持不下来。因此不如把每一次的思考、理解以及别人的看法记录下来。不只加深本身的理解,更要激励本身坚持下去。java

launchMode简介

what(是什么)

是Activity的一种配置属性,表示Activity由哪一种方式启动android

how(怎么用)

有两种配置方式:git

  • 在manifest清单文件中配置默认启动属性。

manifest配置launchMode

  • 在java代码中,启动Activity时指定启动方式,经过inent.addFlags()方法,这里面经常使用的有四种。
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_SINGLE_TOP
    • Intent.FLAG_ACTIVITY_CLEAR_TOP
    • Intent.FLAG_ACTIVITY_CLEAN_TASK

具体的使用以及各类搭配使用说明能够看这个Android 之Activity启动模式(二)之 Intent的Flag属性,写的很详细。github

why(为何须要)

在不一样的场景考虑到不一样形式的Activity实例的复用,选择不一样的加载方式。面试

四种launchMode启动模式

介绍启动模式前,咱们先来了解下Android的Activity管理机制。浏览器

Android采用Task来管理多个Activity,当咱们启动一个应用时,Android就会为之建立一个Task,而后就是启动这个应用程序的入口Activity,并将实例放入Task。app

Android并无为Task提供任何的API,咱们没法真正的访问Task,只有一个getTaskId方法得到所在Task的Id。Task经过栈的方式管理Activity实例,包括先进后出、入栈出栈方式都是同样的。学习

Task栈

standard模式

默认的启动模式。每次启动一个Activity,都会建立一个新的Activity实例放在Task栈顶。这个Task栈是启动新的Activity的Activity所在的Task栈。那么这时候就会有特殊的状况,若是是service或者Application启动的Activity,并无Task栈,这时就须要咱们经过addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)指定标记,建立一个新的Task。ui

standard示例

app的大多数Activity皆采用这种启动模式。做为开发者,咱们考虑到的就是用户在操做每一个页面后,即便之间有重复的界面,按回退键也能够按照刚刚操做的顺序回退。spa

singleTop模式

这种模式存在两种状况:

  • Task栈顶不是要启动的Activity实例,这时和standard模式没有区别
  • Task栈顶是要启动的Activity实例,那么就会复用这个实例,而且回调该Activity的onNewIntent方法。因为不会建立Activity实例,因此不会回调其余方法。

singleTop

通常应用于通知详情页或者聊天界面,即经过点击通知栏消息进入Activity。能够避免有屡次通知消息经过点击而产生较多Activity实例。加强Activity的复用性。

singleTask

这种模式有三种状况。

  • Task栈中不存在要启动的Activity实例,这时和standard模式没有任何区别
  • Task栈中存在要启动的Activity实例,且此实例在栈顶,这时和singleTop模式没有区别
  • Task栈中存在要启动的Activity实例,且此实例不在栈顶。这时会移除此实例上的全部Activity实例,使此实例置于Task栈顶,并复用此实例,回调onNewIntent方法

也就是说这是一种栈内的单例模式。这种模式下还能够经过manifest文件中的taskAffinity属性来指定要加载的Task栈。

<activity 
    android:name=".activitys.MainActivity"
    android:launchMode="singleTask"
    android:taskAffinity="com.gl.task"/>
复制代码

关于taskAffinity的值:每一个Activity都有taskAffinity属性,这个属性指出了它但愿进入的Task。若是一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,若是Application也没有指明,那么该taskAffinity的值就等于包名。

singleTask示例

这种模式通常应用于app的主页,在退出应用程序的时候不须要退出其余的Activity,由于主页通常置于Task栈底部。或者该页面可能会被其余应用程序唤醒,好比浏览器首页。

singleInstance模式

这种模式算是一种全局的单例模式,即只要有任何一个栈存在此Activity实例,就会复用此实例,回调onNewIntent方法。若是此实例不存在,那么就会建立新的Task栈,并放入Activity实例。

也就是说,这种模式下的Activity实例只有两种形式。

  • 不存在此实例
  • 存在此实例,且只在一个Task栈中而且该Task中只有该实例

singleInstance实例

这种模式通常应用于闹钟响铃界面、拨打接听电话界面等系统界面,确保此Activity实例只能存在一个。 常应用于独立栈操做的应用,如闹钟的提醒页面,当你在A应用中看视频时,闹钟响了,你点击闹钟提醒通知后进入提醒详情页面,而后点击返回就再次回到A的视频页面,这样就不会过多干扰到用户先前的操做了。

另外启动其余应用程序中的Activity的操做,在5.0以前新启动的Activity实例会放入启动的Intent所在的Task栈内,虽然他们并不属于同一应用程序。这好像并不怎么合理,因此在5.0后会建立一个新的Task栈存放外部应用程序的Activity实例

相关文章
相关标签/搜索