Activity之启动模式

来源:互联网 发布:java截取字符串的函数 编辑:程序博客网 时间:2024/06/05 10:19

前言 

     转载请注明出处:小石头的博客 http://blog.csdn.net/lu1024188315/article/details/74518599
       Task 是多个 activity 的集合,用户进行操作时将与这些 activity 进行交互。 这些 activity 按照启动顺序排队存入一个栈(即“back stack”)。大部分 task 都启动自 Home 屏幕。当用户触摸 application launcher 中的图标(或 Home 屏幕上的快捷图标)时,应用程序的 task 就进入前台。 如果该应用不存在 task(最近没有使用过此应用),则会新建一个 task,该应用的“mainactivity 作为栈的根 activity 被打开。

      当用户返回到 home屏幕执行另一个 task 时,一个 task 被移动到后台执行,此时它的返回栈(back stack)也被保存在后台, 同时 android 为新 task 创建一个新的返回栈(back stack),当它被再次运行从而返回前台时,它的返回栈(back stack)被移到前台,并恢复其之前执行的activity。 如果后台有太多运行 task ,系统将会杀死一些 task 释放内存。

      如果当前 activity 启动了另一个 activity,则新的 activity 被压入栈顶并获得焦点。 前一个 activity 仍保存在栈中,但是被停止。activity 停止时,系统会保存用户界面的当前状态。 当用户按下返回键,则当前 activity 将从栈顶弹出(被销毁),前一个 activity 将被恢复(之前的用户界面状态被恢复)。 activity 在栈中的顺序永远不会改变,只会压入和弹出——被当前 activity 启动时压入栈顶,用户用返回键离开时弹出。 这样,back stack 以“后进先出”的方式运行。如图, 以时间线的方式展示了多个 activity 切换时对应当前时间点的 back stack 状态。


      task 中的每个新 activity 都会相应在 back stack 中增加一项。当用户按下返回键时,当前 activity 被销毁,前一个 activity 被恢复。
一  启动模式
   Activity共有四种启动模式:standardsingleTopsingleTasksingleInstance
       <activity             android:name=".MainActivity"            android:launchMode="standard">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>
    启动模式是在配置文件中设置的,不设置默认是standard模式。

1  standard

      默认值。系统在启动 新的activity ,就会在task 中创建一个新的 activity 实例,并把 intent 传送路径指向它。 该 activity 可以被实例化多次,各个实例可以属于不同的 task,一个 task 中也可以存在多个实例。

singleTop

      如果 activity 已经存在一个实例并位于当前 task 的栈顶,则系统会调用已有实例的onNewIntent() 方法把 intent 传递给已有实例,而不是创建一个新的 activity 实例。 activity 可以被实例化多次,各个实例可以属于不同的 task,一个 task 中可以存在多个实例(但仅当 back stack 顶的 activity 实例不是该 activity 的),也就是说activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例

      比如,假定 task 的 back stack 中包含了根 activity A 和 activities B、

CD(顺序是 A-B-C-D在栈顶)。 这时过来一个启动 的 intent。 如果 的启动模式是默认的"standard",则会启动一个新的实例,栈内容变为 A-B-C-D-D。 但是,如果 的启动模式是"singleTop",则已有的 实例会通过 onNewIntent() 接收这个 intent,因为该实例位于栈顶——栈中内容仍然维持 A-B-C-D 不变。 当然,如果 intent 是要启动 的,则 的一个新实例还是会加入栈中,即使 的启动模式是"singleTop"也是如此。

singleTask

      系统将创建一个新的 task,并把 activity 实例作为根放入其中。 但是,如果 activity 已经在其它 task 中存在实例,则系统会通过调用其实例的 onNewIntent() 方法把 intent 传给已有实例,而不是再创建一个新实例。 activity同一时刻只能存在一个实例在task中,即Task栈中将会只有一个该Activity的实例。

      例如:现在栈的情况为:A B C D。B的Launch mode为singleTask,此时D通过Intent跳转到B,则栈的情况变成了:A B。而C和D被弹出销毁了,也就是说位于B之上的实例都被销毁了。

      关于singleTask这个网上颇有争议,google api说singTask模式只能启动一个task,且总是位于栈底,这个也不是完全正确

分2种情况:

  (1)如果在同一个应用(apk)中使用singleTask,刚不在栈底,对应于下面的情况一

  (2)如果从不同应用启动一个singleTask的activity,刚依赖于此activity所在的栈,如果之前没有运行过,则新建栈处于栈底,如果有运行过,则有可能不在栈底,对应于情况二

    情况一:如果在本程序中启动singleTask的activity:假设ActivityA是程序的入口,是默认的模式(standard),ActivityB是singleTask 模式,由ActivityA启动,刚ActivityB不会位于栈底,不是根元素,不会启动新的task,此种情况ActivityB会和ActivityA在一个栈中,位于ActivityA上面

  情况二:如果ActivityB由另外一个程序启动:假设apkA是情况一中的应用,apkB是另外一个测试程序,在apkB中启动apkA中的ActivityB,再分两种情况,如果ActivityB未启动过,ActivityB会位于栈底,是根元素,会启动新的task;如果ActivityB启动过,则ActivityB保持原来的位置不变,在栈底或者栈顶,移除掉ActivityB之上所有的activity(如果有),见下图


      此图就是保存了activitY所在的栈的情况,按返回键的时候,会首先依次移除掉activitY所在的栈的activity,然后才是activity2。

       注意singleTask模式的Activity不管是位于栈顶还是栈底,再次运行这个Activity时,都会destory掉它上面的Activity来保证整个栈中只有一个自己。

singleInstance

      singleInstance:将Activity压入一个新建的任务栈中。例如:Task栈1的情况为:A B C。C通过Intent跳转到D,而D的Launch mode为singleInstance,则将会新建一个Task栈2。此时Task栈1的情况还是为:A B C。Task栈2的情况为:D。此时屏幕界面显示D的内容,如果这时D又通过Intent跳转到D,则Task栈2中也不会新建一个D的实例,所以两个栈的情况也不会变化。而如果D跳转到C,则栈1的情况变成了:A B C C,因为C的Launch mode为standard,此时如果再按返回键,则栈1变成:A B C。也就是说现在界面还显示C的内容,不是D。

二 比较

1  如何决定所属task

     “standard”和”singleTop”的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包括参数FLAG_ACTIVITY_NEW_TASK。如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。“singleTask”和”singleInstance”总是把activity作为一个task的根元素,他们不会被启动到一个其他task里。

2  是否允许多个实例

     “standard”和”singleTop”可以被实例化多次,并且可以存在于不同的task中,且一个task可以包括一个activity的多个实例;
     “singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。 singleTop要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。

3 是否允许其它activity存在于本task内

      “singleInstance”独占一个task,其它activity不能存在那个task里;如果它启动了一个新的activity,不管新的activity的launch mode 如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK参数)。而另外三种模式,则可以和其它activity共存。

4  是否每次都生成新实例

     “standard”对于每启动一个Intent都会生成一个activity的新实例;
     “singleTop”的activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例,否则,生成该activity的实例。比如现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D,如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。
      “singleInstance”是其所在栈的唯一activity,它会每次都被重用。
      “singleTask”如果在栈顶,则接受intent,否则,该intent会被丢弃,但是该task仍会回到前台。
当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法 如果收到intent生成一个activity实例,那么用户可以通过back键回到上一个状态;如果是已经存在的一个activity来处理这个intent的话,用户不能通过按back键返回到这之前的状态。



原创粉丝点击