Task和Back Stack(三)

       接着上一篇 Task和Back Stack(二)继续

       如何定义启动模式

       一、 使用Manifest文件
       当你在manifest文件中申明一个Activity的时候,你可以通过其launchMode属性指定该Activity如何与task相关联。
       launchMode会指定一个说明用来决定该Activity应当如何在一个Task中启动。下面是launchMode可用的四种属性值:
       standard(默认值)
       默认情况下,系统会在启动它的Task中创建一个新的Activity实例,并将Intent交付给这个Activity实例。这个Activity可以被多次实例化,每个实例可以属于不同的Task,同一个Task也可以持有该Activity的多个实例。
       singleTop
       假如这个Activity的一个实例已经存在于当前Task的顶端,那么系统会调用Activity的onNewIntent()方法将Intent交付给这个实例,而不会重新创建新的实例。这个Activity可以被多次实例化,每个实例处于不同的task中。同一个task也可以持有多个此Activity的实例(不过,只有在当前back stack的栈顶元素不是这个activity的实例的情况下,才可以)。
       例如,假设一个task的back stack由根Activity A和在他之上的三个Activity B,C,D组成(Back stack组成为A-B-C-D: D为栈顶)。此时,一个Intent指定将一个Activity D为目标。如果 D为默认启动模式"standard",那么一个新的实例Activity D将会被创建,当前back stack变为A-B-C-D-D。不过,如果D的启动模式为singleTop,那么已经存在的D的实例会通过其onNewIntent()方法接收到这个Intent, 因为D已经是当前的栈顶元素,此时Back stack仍为A-B-C-D。假如这个Intent的目标组件是Activity B类型的一个实例那么一个新的 B实例将会被加入栈中,因为启动模式为“singleTop”,此时Back stack变为A-B-C-D-B。
      注意:当一个Activity的新实例被创建的时候,用户可以点击Back 按键回到之前的Activity。但是,当一个Activity的现有实例处理一个新的Intent时,用户不能通过点击回退按钮回到这个Activity通过onNewIntent()接受Intent之前的状态。
       singleTask
       系统会创建一个新的Task,并创建这个Activity的一个实例作为这个Task的根Activity。然而,如果这个Activity的一个实例已经存在于一个独立的Task中,那么系统会调用这个实例的onNewIntent()方法并将Intent交付给这个实例,而不是创建一个新的实例。这样,同一时刻只有一个该Activity的实例存在。
       注意:尽管这个Activity在一个新的Task中被启动,点击回退按键仍然可以回到之前的Activity中。

       singleInstance
       和SingleTask一样(Same as "singleTask",),不过,系统不会启动任何其他的Activity到这个Task中,既此时这个Task是独立的,也仅持有一个Activity的实例。

   

       另一个例子:android的浏览器应用申明需要web浏览器的两个Activity页面在他们各自的Task中开启---通过在manifest中指定启动模式为singleTask完成。这就意味着,假如你的应用分流出一个Intent来打开android的浏览器,那么这个Activity不会被放置到你自己的应用Task中。而是,或者会为浏览器开启个新的Task,或者,假如该浏览器已经启动整运行与后台,那么这个后台Task会被带到前台来处理你的新的Intent。
       无论一个Activity是存在于一个新开启的Task中,还是存在于启动它的Activity的Task中,Back按键都会回退到之前的Activity。然而,假如你开启了一个启动模式为singleTask的Activity,并且这个Activity的一个实例已经存在于一个后台运行的Task中,那么,这个后台Task整个会被带到前台。这时,back stack的栈顶将包含后台Task的所有Activity。(是否意味着点击Back按键并不会回到前一个Activity?,而是会按照这个Activity中最初运行的Back Stack回退。如下图示,确实是这样的。

Task和Back Stack(三)_第1张图片

表4.展示了一个启动模式为singleTask的Activity如何被加入到back stack中。假如这个Activity已经是一个后台Task对应的back stack的一部分,那么整个back stack也会被带到前台,处于当前Task之上。
注意:你通过launchMode指定的启动方式会被启动这个Activity的Intent中指定的Flags覆盖,下一篇将详解这一点。


附注:对于启动模式singleTask,我反复查看文档,并通过实例在Activity中用getTaskId()打印当前Task的Id发现,当进入启动模式为singleTask的Activity时,并没有重新创建过task。操作结果显示,如果当前Task中没有该Activity的实例,那么系统会在当前task对应的back stack栈顶新建一个实例,如果当前task中存在该Activity的一个实例,那么对应back stack中在该实例之上的所有Activity都会被出栈并销毁。这就涉及到我之前的问题,如果会新建task,那么数据无法回传可能是因为task不同的原因,而如果像我实例结果中显示的没有新建,那么数据无法回传,是不是因为此时Activity回传数据时,在同一个back stack中的Activity已经被销毁销毁了呢?可是启动模式singleInstance中一句Same as "singleTask"的意思不就是再次说明会新建的么?不知道有没有人碰到过同样的情况。

下面文档中关于singleTask的原文和我的实践过程:

Task和Back Stack(三)_第2张图片

Task和Back Stack(三)_第3张图片

A、B、C表示第一、二、三个Activity。

你可能感兴趣的:(singletask,启动模式,singletop)