Activity的启动模式的深入理解

来源:互联网 发布:php从数据库读取数据 编辑:程序博客网 时间:2024/06/05 19:21

   activity的启动模式共有4中,都与任务栈有着密切的关系。了解启动模式之前,必须先了解栈以及任务栈的含义。接下来,就让我们理解理解“栈”这种数据结构的操作。

1.认识“栈”与“任务栈”

  1.1 栈:是一种常用的数据结构,他的存储方式是“后进先出”,它就好比一个桶,当你向里头放东西只能从上面的口放,并且先添加进去的东西被压在下面,这种操作方式称为“压栈”,当你取东西时你总会先将后面添加进去的东西取出来,这称为“弹栈”。它也是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行,也就是栈顶进行插入和删除。

image

  1.2 栈的基本运算:

    构造空栈:InitStack(S)

    判栈空: StackEmpty(S)

    判栈满: StackFull(S)

    进栈: Push(S,x)可形象地理解为压入,这时栈中会多一个元素

    退栈: Pop(S) 可形象地理解为弹出,弹出后栈中就无此元素了。

    取栈顶元素:StackTop(S),不同与弹出,只是使用栈顶元素的值,该元素仍在栈顶不会改变。

  1.3 任务栈:

  任务是一个Activity的集合,它使用顺序栈的方式来管理其中的Activity,这个栈又被称为返回栈(back stack),栈中Activity的顺序就是按照它们被打开的顺序依次存放的。手机中的主界面通常是任务栈的开始,当用户点击某一个应用图标,这个应用的任务就会被转移到前台,倘若这个应用目前没有任何一个任务的话,也就是说他最近没被打开过,系统会自动新创建一个任务,将这个应用的MainActivity放置到其中。当你从MainActivity跳转到其他的Activity时,此时MainActivity会置于任务栈的栈底而你新打开的Activity会放到它的上面。如果用户一直地按Back键,这样返回栈中的Activity会一个个地被移除,直到最终返回到主屏幕。当返回栈中所有的Activity都被移除掉的时候,对应的任务也就不存在了。

2.Activity的LaunchMode

目前Android共有4种启动模式:standard(标准模式)、singleTop(栈顶复用模式)、SingleTask(栈内复用)、singleInstance(单实例模式)。

   2.1 standard:
  标准模式,也是系统模式的启动模式,不管这个实例存不存在,每次系统启动activity都会创建一个新的。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的实例当中。举个例子:A—->B(标准模式),B就会进入A所在的栈中。换句话说,就是谁启动这个activity,那么这个activity就运行在启动它的activity所在的任务栈中。

注意:当我们用ApplicationContext去启动标准模式的Activity时就会报错,那是因为非activity的类型的上下文Context并没有所谓的任务栈。

解决办法:为待启动的Activity添加一个标志位:FLAG_ACTIVITY_NEW_TASK,为其创建一个新的任务栈就可以了。

   2.2 singleTop:

   栈顶复用,在这种模式下,A—–>B(栈顶模式),倘若B处于任务栈的栈顶,那么B将不会重新创建,它将会被复用。同时他的onNewIntent();方法会被调用,我们可以通过这个方法的参数获得我们想要的请求信息。由于B Activity并没有被重新创建,故而他的生命周期的oncreat,以及onstart并不会被调用。但是当他没有在栈顶时,他还是会被重新创建。举个栗子:假设目前栈内有A,B,C,D四个Activity,A在栈底,D在栈顶,倘若D的启动模式为singleTop,那么栈内情况仍然为A,B,C,D,如果D的启动模式为标准模式的话,那么栈内的情况就会变为A,B,C,D,D。

   2.3 singleTask:

   栈内复用:这是一种单实例模式,也就是说,在这种模式下只要一个Activity的实例在这个栈中存在,那么不管你调用多少次他都不会被重新创建,系统也会回调其onNewIntent方法。 举个例子:具有singleTask模式的Activity A请求启动后,首先系统会寻找是否存在A想要的任务栈,没有的创建一个,并创建A的实例并将A压入栈中,如果有,再看A的实例是否在任务栈中存在,若存在,则将A调到栈顶,并调用他的onNewIntent方法。也就是说A上面如果还有其他的实例存在,那么他们就会被清空,A会位于栈顶。

   2.4 singleInstance:

   单实例模式,这是一种加强的singleTask,他除了所有singleTask的特性外,还有一点,具有此种模式的activity只能单独的位于一个任务栈中。举个例子:A 是singleinstance模式,当A启动后,系统会为其创建一个新的任务栈,A独自在这个新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个任务栈被系统销毁。

下面用图来说明:

这里写图片描述

注意:

  • 解释一下什么叫Activity所需的任务栈:TaskAffinity,这个参数翻译为任务相关性,标识了一个任务栈的名字,默认情况下,所有Activity所需的任务栈的名称为应用的包名,我们可以单独为Activity指定其属性值,但是不能喝包名相同,否则没有意义,并且其主要和singleTask模式或者allowTaskReparenting属性配对使用。
  • 任务栈分为前台任务栈和后台任务栈。后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

3.给Activity指定启动模式

   3.1 AndroidMenifest的方式:

        <activity            android:name=".ui.activity.MigratePlanActivity"            android:exported="false"            android:screenOrientation="portrait"            android:launchMode="singleTask"            android:windowSoftInputMode="stateHidden" />

   3.2AndroidMenifest的方式:

        Intent intent=new Intent();        intent.setClass(this, MainActivity.class);        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        startActivity(intent);

注解:这两种启动方式都可以为Activity指定启动模式,二者的区别在于:

  • 第二种方式的优先级高于第一种,两种同时存在以第二种为准。
  • 二者的限定范围不同,第一种方式没法为Activity直接设置FLAG_ACTIVITY_CLEAR_TOP标记,而第二种方式没法给Activity指定singleInstance模式。

4.Activity中的Flags

  Activtity中的标志位很多,作用也不一样,有的标记位可以设定Actiivity的启动模式FLAG_ACTIVITY_NEW_TASK,FLAG_ACTIVITY_SINGLE_TOP;有的标记位可以影响Activity的运行状态,如:FLAG_ACTIVITY_CLEAR_TOP,FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS等。

   4.1 FLAG_ACTIVITY_NEW_TASK:

      为Activity指定“singleTask”启动模式

   4.2 FLAG_ACTIVITY_SINGLE_TOP:

      为Activity指定“singleTop”启动模式

   4.3 FLAG_ACTIVITY_CLEAR_TOP:

     如果跟singleTask启动模式一起出现,如果被启动的Activity已经存在实例,则onNewIntent方法会被回调,如果被启动的Activity采用standard模式启动,那么连同它跟它之上的Activity都要出栈,并且创建新的实例放入栈顶。

   4.4 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:

     新的Activity不会在最近启动的Activity的列表中保存。等同于指定属性android:excludeFromRecents=”true”

原创粉丝点击