魅力程序猿

  • 首页
  • Java
  • Android
  • APP
    • 扑克计分器
    • Video Wallpaper
  • 联系我
  • 关于我
  • 资助
道子
向阳而生
  1. 首页
  2. Android
  3. 正文

Android面试题1--Activity的4种启动模式

2016年11月20日 8531点热度 0人点赞 4条评论

对Android而言,Activity有四种启动模式,它们是:

1. standard 标准模式也是默认模式,每次都新建一个实例对象。

2. singleTop 如果在任务栈顶发现了相同的实例则重用,否则新建并压入栈顶。

3、singleTask 如果在任务栈中发现了相同的实例,将其上面的任务终止并移除,重用该实例。否则新建实例并入栈。

4、singleInstance 允许不同应用,进程、线程等共用一个实例,无论从何应用调用该实例都重用。

想要感受一下的话写一个小demo,然后自己启动自己再点返回键就看出来了。下面详细说说每一种启动模式。

一、standard

这个模式是默认的启动模式,即标准模式,在不指定启动模式的前提下,系统默认使用该模式启动Activity,每次启动一个Activity都会重写创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。

配置形式:

<activity android:name=".ActivityStandard" android:launchMode="standard" >

如图描述:

activity_standard

这也验证了谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中这句话,因为启动ActivityStandard的是ActivityMain,而Main的ActivitytaskId是2016,因此启动的ActivityStandard也应该属于id为2016的这个task,后续的1个ActivityStandard是被ActivityStandard这个对象启动的,因此也应该还是2016,所以taskId都是2016。并且每一个Activity的hashCode都是不一样的,说明他们是不同的实例,即“每次启动一个Activity都会重写创建一个新的实例”

二、singleTop

这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。如果栈顶不存在该Activity的实例,则情况与standard模式相同。

配置形式:

<activity android:name=".ActivitySingleTop" android:launchMode="singleTop">

如图描述1:

activity_singletop

这种情况,第一次进入ActivitySingleTop这个Activity时,会走onCreate方法,第二次调用了onNewIntent方法,并没有调用onCreate方法,并且两个的hashcode都是一样的,说明栈中只有一个实例。这是因为第一次进入的时候,栈中没有该实例,则创建,第二次发现栈顶有这个实例,则直接复用,并且调用onNewIntent方法。

如图描述2:

activity_singletop2

从ActivityMain进入到ActivitySingleTop时,新建了一个ActivitySingleTop对象,并且task id与ActivityMain是一样的,然后从ActivitySingleTop跳到ActivityOther时,新建了一个ActivityOther,此时task中存在三个Activity,从栈底到栈顶依次是ActivityMain,ActivitySingleTop,ActivityOther,此时如果再跳到ActivitySingleTop,即使栈中已经有ActivitySingleTop实例了,但是依然会创建一个新的ActivitySingleTop实例,这一点从hashCode可以看出,此时栈顶是ActivitySingleTop,如果再跳到ActivitySingleTop,就会复用栈顶的ActivitySingleTop,即会调用ActivitySingleTop的onNewIntent方法。

总结  standard和singleTop启动模式

standard启动模式是默认的启动模式,每次启动一个Activity都会新建一个实例不管栈中是否已有该Activity的实例。

singleTop分三种

1、当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法。

2、当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例。

3、当前栈中不存在该Activity的实例时,其行为同standard启动模式

standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task,即使你指定了taskAffinity属性。

那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。

.这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名

.我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值

.一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity

.在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务

.为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task

很重要的一点taskAffinity属性不对standard和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的task(如果不指定即默认值,即包名)

指定方式如下:

<activity android:name=".ActivitySingleTop" android:launchMode="singleTop" android:taskAffinity="com.aoaoyi.demo.singletop"/>

<activity android:name=".ActivityStandard" android:launchMode="standard" android:taskAffinity="com.aoaoyi.demo.standard"/>

三、singleTask

这个模式十分复杂,有各式各样的组合。在这个模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。

配置形式:

<activity android:name=".ActivitySingleTask" android:launchMode="singleTask" >

如图描述1:

activity_singletask

当我们从ActiviytyMain进入到ActivitySingleTask,再进入到ActivityOther后,此时栈中有3个Activity实例,并且ActivitySingleTask不在栈顶,而在ActivityOther跳到ActivitySingleTask时,并没有创建一个新的ActivitySingleTask,而是复用了该实例,并且回调了onNewIntent方法。并且原来的ActivityOther出栈了,具体见下面的信息,使用命令adb shell dumpsys activity activities可进行查看

activity_singletask1

可以看到当前栈中只有两个Activity,即原来栈中位于ActivitySingleTask 之上的Activity都出栈了。
我们看到使用singleTask启动模式启动一个Activity,它还是在原来的task中启动。其实是这样的,我们并没有指定taskAffinity属性,这说明和默认值一样,也就是包名,当ActivityMain启动时创建的Task的名字就是包名,因为ActivityMain也没有指定taskAffinity,而当我们启动Activity SingleTask,首先会寻找需要的任务栈是否存在,也就是taskAffinity指定的值,这里就是包名,发现存在,就不再创建新的task,而是直接使用。当该task中存在该Activity实例时就会复用该实例,这就是栈内复用模式。

这时候,如果我们指定ActivitySingleTask 的taskAffinity值。

<activity android:name=".ActivitySingleTask" android:launchMode="singleTask" android:taskAffinity="com.aoaoyi.demo.singletask"/>

如图描述2:

activity_singletask2

看到SingleTaskActivity所属的任务栈的TaskId发生了变换,也就是说开启了一个新的Task,并且之后的ActivityOther也运行在了该Task上 。

结论

singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈

如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去

如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例
如果存在实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法
如果不存在该实例,则新建Activity,并入栈

此外,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去。

四、singleInstance

该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。

配置形式:

<activity android:name=".ActivitySingleInstance" android:launchMode="singleInstance" >

activity_singleinstance

第一个应用启动ActivitySingleInstance时,由于系统中不存在该实例,所以新建了一个Task,按home键后,使用另一个App进入该Activity,由于系统中已经存在了一个实例,不会再创建新的Task,直接复用该实例,并且回调onNewIntent方法。可以从他们的hashcode中可以看出这是同一个实例。因此我们可以理解为:SingleInstance模式启动的Activity在系统中具有全局唯一性。

Activity想的Flag相关,请看 Android面试题4--Activity之Intent的Flag

 

Android面试题2--Activity数据的保存和恢复

 

标签: Activity的4种启动模式 Android
最后更新:2016年11月20日

daozi

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

  • clash of clans for windows phone

    Good Day, happy that i found on this in yahoo. Thanks!

    2017年9月26日
    回复
  • hacks bundle activation key

    Me enjoying, will read more. Cheers!

    2017年9月28日
    回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    回复 clash of clans for windows phone 取消回复
    搜索
    联系方式

    QQ群:179730949
    QQ群:114559024
    欢迎您加入Android大家庭
    本人QQ:136049925

    赐我一丝安慰
    给我一点鼓励

    COPYRIGHT © 2023 魅力程序猿. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    豫ICP备15000477号