Android 面试(一):说说 Activity 的四种启动模式

说说 Android 的四种启动模式

这基本是一道必考题,和「 Activity 的生命周期 」一样,基本为必考题。
其实很多人可能存在一个误区,觉得知道这个启动模式「launchMode」没什么意义,但我在毫无准备的前提下,被问到这个问题的时候,我被问的瑟瑟发抖。

这些都是基本

先普及下可能大多数人都知道的基本见解。

  • standard 这是 Activity 的默认启动模式,每次激活 Activity 的时候都会创建一个新的 Activity
    实例,并放入任务栈中。使用场景:基本绝大多数地方都可以用。

Android 面试(一):说说 Activity 的四种启动模式_第1张图片 - singleTop 这可能也是非常常用的 launchMode 了。如果在任务的栈顶正好存有该 Activity 的实例,则会通过调用
onNewIntent() 方法进行重用,否则就会同 standard 模式一样,创建新的实例并放入栈顶。即便栈中已经存在了该
Activity 的实例,也会创建新的实例,即:A -> B ->A,此时栈内为 A -> B -> A,但 A -> B ->B
,此时栈内为 A -> B。一句话概述就是:当且仅当启动的 Activity 和上一个 Activity 一致的时候才会通过调用
onNewIntent() 方法重用 Activity
。使用场景:资讯阅读类 APP 的内容界面。
Android 面试(一):说说 Activity 的四种启动模式_第2张图片

  • singleTask 这个 launchMode专门用于解决上面 singleTop 的另外一种情况,只要栈中已经存在了该
    Activity 的实例,就会直接调用 onNewIntent() 方法来实现重用实例。重用时,直接让该 Activity
    的实例回到栈顶,并且移除之前它上面的所有 Activity 实例。如果栈中不存在这样的实例,则和 standard 模式相同。即: A
    ->B -> C -> D -> B,此时栈内变成了 A -> B。而 A -> B -> C,栈内还是 A -> B -> C。使用场景:浏览器的主页面,或者大部分 APP 的主页面。
    Android 面试(一):说说 Activity 的四种启动模式_第3张图片
  • singleInstance 在一个新栈中创建该 Activity 的实例,并让多个应用共享该栈中的该 Activity
    实例。一旦该模式的 Activity 实例已经存在于某个栈中,任何应用再激活该 Activity 时都会重用该栈中的实例,是的,依然是调用
    onNewIntent() 方法。其效果相当于多个应用共享一个应用,不管是谁激活,该 Activity
    都会进入同一个应用中。但值得引起注意的是:singleInstance 不要用于中间页面,如果用户中间页面,跳转会出现很难受的问题。
    这个在实际开发中我暂未遇到过,不过 Android 系统的来电页面,多次来电均是使用的同一个 Activity 。
    Android 面试(一):说说 Activity 的四种启动模式_第4张图片
    四种模式的背书式理解记忆讲完了,你认为这样就结束了吗?
    对,我也一度是这样认为的。

再说说我们的 Intent 标签

我们除了需要知道在 AndroidManifest.xml 里面设置 android:launchMode 属性,我们还需要了解下面这几个 Intent 标签的用法。
我们当然可以选择看看官方文档 Tasks and Back Stack (你可能需要梯子)。
在 Android 中,我们除了在清单文件 AndroidManifest.xml 中配置 launchMode,当然可以用 Intent 标签说事儿。启动 Activity ,我们需要传递一个 Intent,完全可以通过设置 Intent.setFlags(int flags) 来设置启动的 Activity 的启动模式。
需要注意的是:通过代码来设置 Activity 的启动模式的方式,优先级比清单文件设置更高。

  • FLAG_ACTIVITY_NEW_TASK 这个标识会使新启动的 Activity 独立创建一个 Task。
  • FLAG_ACTIVITY_CLEAR_TOP 这个标识会使新启动的 Activity 检查是否存在于 Task
    中,如果存在则清除其之上的 Activity,使它获得焦点,并不重新实例化一个 Activity,一般结合
    FLAG_ACTIVITY_NEW_TASK 一起使用。
  • FLAG_ACTIVITY_SINGLE_TOP 等同于在 launcherMode 属性设置为 singleTop。
    Android 面试(一):说说 Activity 的四种启动模式_第5张图片
    前面讲了这么多,似乎相当全面了,但你以为这样就结束了?No,面试官一般情况下已经不会这么问你了,这样问你完全可以背出来。

面试官怎么问 Activity 的启动模式(launchMode)?

怎么问?

1、设置为 singleTask 的启动模式,当 Activity 的实例已经存在时,再启动它,它的哪个回调函数会被执行?我们可以在哪个回调中处理新的 Intent 协带的参数?(通过 startActivity(Intent) 方式启动)
2、设置为 singleTop 的启动模式,当 Activity 的实例已经存在于 Task 的栈顶,我们可以在哪个回调中处理新的 Intent 协带的参数?(在当前 Activity 中从通知栏点击再跳转到此 Activity 就是这种在栈顶的情况)

这两个问题如果你看了上面的,一定对你来说实在太简单了。面试官只是想直接考察你是否真正做过这样的设置,或者是否知道 onNewIntent() 这个方法的存在。

有没有其他想说的?

有。
之前在「柳学兄」的文章中看到过这样一种情况,发现之前同事写的代码导致了这样一个问题。

startActivityForResult 启动一个 Activity,还没有开始界面跳转,直接就执行了
onActivityResult()。

不知道有没有人也遇到过这样的问题,但我想遇到这个问题的时候,你一样会因此而抓耳挠腮。(可能是因为我们一般在排查问题的时候,很少去关注配置清单文件 AndroidManifests.xml。)
我们在 Activity.java 的 startActivityForResult() 方法中可以看到这样一串说明。
Android 面试(一):说说 Activity 的四种启动模式_第6张图片
很多人出现这个问题,确实是因为 startActivityForResult() 启动的 Activity 设置了 singleTask 的启动模式。
好在 Android 5.0 以后,修正了这个问题。不过当你在 Intent 中设置 FLAG_ACTIVITY_NEW_TASK 后还是会出现这样的问题。

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

注意:MainActivity 的 onResume() 也会被触发。因为 onActivityResult()
被执行时,它会重新获得焦点。很多人也会遇到 onResume() 被无故调用,也许就是这种情况。

所以,最终我们发现只要是不和原来的 Activity 在同一个 Task 就会产生这种立即执行 onActivityResult() 的情况,从原代码也可以得到验证,详情查看 ActivityStackSupervisor.java。

小结

关于 Activity 的启动模式相关的问题,其实还会有很多种考察你掌握情况的问法,建议采用 STAR 法则 进行面试回答。其实只要你掌握了实质,后面的运用只看你个人的运用能力和创新了。
想学习更多Android知识,或者获取相关资料请加入Android技术开发交流2群:935654177。本群可免费获取Gradle,RxJava,小程序,Hybrid,移动架构,NDK,React Native,性能优化等技术教程!

你可能感兴趣的:(Android,程序员,Android开发,Android应用,Android技术)