本文主要分析Activity的启动模式及使用场景。

一、Activity启动模式浅析
1、standard
标准模式,系统默认的启动模式。在启动Activity时,系统总是创建一个新的Activity实例。其缺点是:复用性差、占用内存,当Activity已经在栈顶时,还是会创建实例。 2、singleTop
这种模式可以实现栈顶复用的效果。
如果目标Activity已经存在于栈顶,则调用实例的 onNewIntent,否则创建一个新的实例,可以用于通知启动的内容显示,例如新闻客户端的内容页面。信息类应用的列表Activity往往也会使用这种启动模式,例如,收到新短信时,如果信息列表Activity已经在栈顶了,则直接调用其onNewIntent,而不需要创建新的Activity。
该模式下,当Activity不在栈顶时,还是会创建新的实例。例如A、B、C三个Activity处于一个任务栈中,且C在栈顶,如果C启动A,则会创建一个新的实例并置于栈顶,使得当前任务栈有两个A实例。 3、singleTask
该模式实现栈内复用的效果。如果栈内已经有目标Activity实例,则清除目标Activity上面的所有Activity、使得目标Activity直接放到栈顶,并调用目标Activity的onNewIntent方法;否则创建一个新的Activity实例。
补充,该模式Activity会在跟它有相同taskAffinity的任务中启动,并且位于这个任务的堆栈顶端,这样如果我们没有设置taskAffinity,从本应用启动的Activity就会复用当前Task,也就不会创建一个新的Task。
该启动模式,适合作为程序入口点,例如原生Launcher以及相机应用中的CameraActivity,就是使用了这种启动模式。 4、singleInstance
系统级的复用。启动Activity时,如果系统中不存在该Activity实例,则创建一个新的ActivityTask,并且独占这个Task,否则显示已有的Activity实例。通常用于系统级的应用,在整个系统中只有一个实例,例如来电提醒、闹钟提醒。 这四种启动模式创建一个新Activity实例的几率,是依次降低的。实际在使用时,往往会用到动态设置启动模式,给Intent设置特定的Flag,例如FLAG_ACTIVITY_SINGLE_TOP(对应singleTop)、FLAG_ACTIVITY_NEW_TASK(对应singleTask)。 二、使用中的注意事项
首先要注意Flag的动态设置方式,优先级高于静态方式(通过AndroidManifest.xml设置)。如果这两种设置方式混合在一起,则Activity启动过程、最终效果要分为多种情况来考虑。 其次,从非Activity组件例如Service启动Activity时,必须添加FLAG_ACTIVITY_NEW_TASK这个Flag。可以思考下,系统这样设计的原因? 再次,由于部分启动模式在启动Activity时,有时候并不会重新创建一个实例,也就不会调用其onCreate方法,而是回调onNewIntent方法,如果在启动时需要根据Intent重新加载数据,注意在onNewIntent中添加对应的处理。由于Activity在某些情况下,可能会被系统销毁,为了保险,Intent获取数据的处理,最好在onCreate、onNewIntent这两个函数中都做添加。 最后,如果我们用了FLAG_ACTIVITY_CLEAR_TOP这个flag启动Activity,当栈内已有目标Activity实例时,系统的处理会分为两种情况:
a. 只设置了FLAG_ACTIVITY_CLEAR_TOP,系统会销毁目标Activity和它之上的所有Activity,重新创建目标Activity,并不调用其onNewIntent方法。
b. 设置了FLAG_ACTIVITY_CLEAR_TOP+FLAG_ACTIVITY_SINGLE_TOP,系统只销毁之上的所有Activity,复用目标Activity,调用onNewIntent方法,效果相当于设置FLAG_ACTIVITY_NEW_TASK,也就是singleTask模式。 补充,适合使用singleInstance启动模式的Activity,基本都具有高优先级、业务逻辑的交互相对简单,也就是与其他应用的交互场景不多。而singleTask模式更适用于那些具有一定频度的交互场景的Activity,例如图库、联系人、一些第三方App问问需要启动相机拍照,然后再返回,这时候如果使用singleInstance则会始终独占一个任务栈,体验不好。换句话说,启动模式的设计,本质就是为了优化窗口返回的层次关系,改善用户体验。这其中又涉及到了Android任务栈模型,在后面文章继续分析。

(相关完整且成体系的文章可参见本人原创的开源电子书《Android系统与性能优化》,地址:https://github.com/carylake/androidnotes)

最新文章

  1. Dnsmasq安装与配置
  2. Channel
  3. Java GC收集器配置说明
  4. angularjs controller的两种写法
  5. 专题:点滴Javascript
  6. Apache中压力测试工具ab的操作说明
  7. 4,帮助命令man
  8. SSDP 简单服务发现协议
  9. erl_0011 erlang 定时器相关
  10. oracle SQL Develop导出数据库中的表格数据到excel
  11. 在Android中访问内置SE和基于SE的卡模拟(一)
  12. linux进程间通信之信号
  13. Java Drp项目实战——Drp知多少
  14. Dos命令将合并两个文本文件的内容
  15. UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie
  16. Unity脚本自动添加注释脚本及排版格式
  17. 剑指offer(55)链表中环的入口节点
  18. 大表分批删除脚本之MySQL版
  19. Nginx配置虚拟主机
  20. RabbitMQ理论

热门文章

  1. PHP页面跳转三种实现方法
  2. 封装扩展Kendo UI Grid
  3. java前端与后端怎么选??
  4. 使用modelarts部署bert命名实体识别模型
  5. luogu P4302 [SCOI2003]字符串折叠
  6. [开源] .Net 使用 ORM 访问 达梦数据库
  7. Evevt Loop 事件循环
  8. ZooKeeper初步
  9. [TimLinux] 开博一个月了
  10. HDU5973 Game of Geting Stone(威佐夫博弈)