launch_adv

Android Activity的4种LaunchMode

Activity有4种启动模式,分别是Standard,SingleTop,SingleTask,SingleInstance。要了解清楚这四种模式,必须先解释清楚两个概念,分别是Task和Activity Back Stack。Task可以理解成一系列Activity的合集,这个合集是已栈(Stack)的形式来存放Activity的,如图:

task

Task又可以有前台(Foreground)和后台(Background)两种状态,比如当前用户正在交互的app它的task就是在前台的,如果此时用户按下Home键当前的这个task就会转成后台的状态,后台的task里的Activity将停止。如果用户再次点击这个app的图标,这个task将再次返回前台。Activity的Back Stack是这样工作的,用户当前交互的Activity总是在栈顶的,假设当前用户在Activity A里,此时点击了一个按钮打开了Activity B,此时B就会被压到栈顶,栈里的内容将是 A-B,如果用户在B中又开启了Activity C,栈内容将变成A-B-C。如果此时按Back键,Activity C将会被弹栈,B将成为栈顶再次被用户可见。这里唯一需要注意的问题是,这个Stack里的Activity顺序是不能改变(rearrange),这个栈只能进行push和pop的操作。

有了前面的知识,我们就可以开始解释4种Launch Mode了:

  • Standard

这个是Android的默认标准模式,每次打开一个Activity都将新创建一个Activity压入栈中,比如现在栈里的情况是有A-B-C这三个Activity,我们想在C中再打开一个Activity C,此时Android的默认行为将是新建一个Activity并压栈,栈里的内容将变为A-B-C-C。很容易看出,在某些使用情况下种子模式会产生一种很糟糕的用户体验,比如在一个Activity里可以点开搜索功能(SearchActivity),每次重新搜索将会重新打开SearchActivity,如果用户反复搜索10次,在Standard模式下,SearchActivity将会被重复创建10次,压栈10次,用户如果想通过按Back返回到原来的Activity那得按10次才能返回到最初的Activity!

standard_problem

 

  •   SingleTop

这种模式刚好可以解决上述的问题。它是这样工作的,如果当前要打开的Activity刚好已经存在于Back Stack的顶端它将不再重新创建一个Activity而是使用原来的Activity。比如现在栈里的Activity有A-B-C,如果我想在C中再打开一个Activity,此时发现栈顶已经有C了,我们就直接使用这个C而不是重新创建一个Activity压栈了。当然如果栈里是A-B-C,此时要打开B,还是会重新创建B并压栈。

  • SingleTask

SingleTask的Activity永远在task的根部,意思是如果这个Activity不在当前的Task的根部,它会新建立一个Task然后进行压栈。如果这个SingleTask Activity在当前task的根部,在这个Activity之上的所有Activity将进行弹栈,保证这个SingleTask Activity重新到达栈顶。如栈里有A-B-C-D,若Activity A定义为SingleTask模式,此时在D里我们要再打开一个A,栈里B,C,D将会被弹栈。若栈内为B-C-D (task1),在D中需要打开一个A,将会新建一个新的task2,里面压入A。这里还有一种情况,如果当前的task1的栈里有A-B-C (假设E为SingleTask Activity),这个时候需要打开E,且当前的系统里E已经存在了在task2中为 D-E-F,此时系统会把task2中E以上的Activity弹栈,task2切到前台(foreground),task1在后台(background),如果一直按下back键将把task2里的所有Activity清空了,才可以回到task1里。

  •  SingleInstance

这种模式和singleTask基本相同,唯一的不同的地方是定义为singleInstance的Activity单独存在于一个task里,其上不能再压入Activity。举一个例子,现在我有A,B,C三个Activity,其中Activity B是定义为SingleInstance的,如果我在A中启动B(A在task1里),B将新建一个task2并压入其中,如果在Activity B中我们再打开C,此时C将压入task1的栈而不是task2的栈!此时task1的栈中元素将是A-C,task2的栈是B。此时若回退将从C->A->B这个顺序回退.

总结:我们可以把4种LaunchMode分成两类,一类是Activity可以多次实例化的,如Standard和SingleTop,另一类则是Activity都是单例的(Singleton)的,如SingleTask和SingleInstance。通过改变Activity的LaunchMode在一定的场景下可以获得更好的交互体验。

参考:

ps:这个问题以前自己没有注意过,面试的时候没有当上来,写一篇博客纪念一下。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>