1. Activity的生命周期

正常情况下的Activity生命周期如下图所示(来自Android Developer):

当资源相关的系统配置变更时(比如设备屏幕方向改变,键盘可见性变化),会导致Activity的销毁与重建。某些系统配置变更时,系统会根据最新配置重新为应用加载适合于当前配置的资源,这些系统配置就是资源相关的系统配置。此时在销毁Activity前会调用onSaveInstance()方法已保存当前的状态信息,这个方法会在onStop()前被调用,但与onPause()的时序关系不确定。当Activity被重新创建后,onRestoreInstanceState()方法会被调用以恢复之前保存的状态信息,这个方法具体的调用时机是在onStart()之后。

onSaveInstanceState()方法只有在被销毁的Activity随后会重新被创建时才会被调用,主要有如下两种情况:

  • 一个就是我们上面提到的资源相关的系统配置变更时;

  • 另一个情况就是系统内存不足导致低优先级的Activity被杀死,这种情况下系统在销毁Activity时会调用onSaveInstanceState()方法,并且随后当被杀死的Activity重新启动时,onRestoreInstanceState()方法会被回调。

2. Acitivty的四种启动模式

在介绍Activity前,我们先简单地介绍一下任务栈(back stack)的概念。假设我们从桌面首次启动了某个App,系统会开启一个新的任务栈并把该App的MainActivity(设为Activity1)加入这个任务栈中,若之后我们在新启动的App中又打开了Activity 2、Activity 3,则Activity 2和Activity 3也会被依次压入这个任务栈中。于是现在任务栈的栈顶就是Activity 3了,我们与之交互的Activity始终是当前任务栈栈顶的Activity。现在我们点击了Back键,则Activity 3会被弹出任务栈,当前栈顶的Activity即变为了Activity 2,我们开始与Activity 2进行交互。

以上过程可用下图来描述:

(1)standard:标准模式(默认)

以standard模式启动的Activity会被放入启动它的那个Activity所在的任务栈(Back Stack)中。在我们调用Context.startActivity方法去启动standard模式的Activity时会报错, 因为ApplicationContext并没有关联一个任务栈,解决方案是为待启动Activity指定FLAG_ACTIVITY_NEW_TASK标记位,此时会新键一个任务栈,并把刚启动的Activity放入其中,这种情况下被启动Activity实际上以singleTask模式启动。以standard模式启动Activity的话,若多次启动会创建多个Activity实例。

(2)singleTop:栈顶复用模式

若待启动Activity位于栈顶,则复用之,不会再new一个实例。此时待启动Activity的onNewIntent方法会被调用。

若待启动Activity不在栈顶,则还是会创建一个它的实例。

(3)singleTask:栈内复用模式

只要Activity已存在于“它想在的栈”中,就复用这个栈中已存在的Activity实例,而不会创建新实例。通过为Activity指定TaskAffinity属性可指定它想在的栈,默认为应用包名。TaskAffinity属性主要和singleTask启动模式或是allowTaskReparenting属性配对使用。若Activity在它想在的栈中,此时待启动Activity的onNewIntent方法会被调用。

当我们启动一个singleTask模式的Activity时,系统会先查找是否存在待启动Activity想在的栈,若有的话,则看那个栈中是否有它的实例,若有则把这个实例调整到栈顶并调用其onNewIntent方法;若实例不存在,则创建一个该Activity实例并放入栈中。若找不到想在的栈则新建一个栈,再创建一个待启动Activity的实例并放进去。

singleTask自带clearTop效果:若待启动的Activity位于它想在的栈中(但不在栈顶),则系统会把它上面的Activity全部出栈,让待启动Activity的实例“提升”到栈顶。

(4)singleInstance:单实例模式

这是一种加强的singleTask模式。它除了具有singleTask的所有特性外,还加强了一点:具有此种模式的Activity所在的任务栈中只能有它一个Activity。系统总是会为以singleInstance模式启动的Activity创建一个新的任务栈,再创建一个它的实例放进去。

最后我们介绍一下allowTaskReparenting属性:当App A启动了App B的某个Activity后,若被启动Activity的allowTaskReparenting属性为true,那么当App B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈。因为实际上App B中的Activity的TaskAffinity属性为App B的包名,所以它本应属于B的任务栈,但App B此时未启动,所以它暂时在A的任务栈中待着。当我们一旦把相应Activity的allowTaskReparenting属性设为true时,待到时机成熟(App B被启动),这个Activity就会去本该属于它的地方。

3. 参考资料

(1)Android Developer

(2)《Android开发艺术探索》

十分钟掌握Activity的生命周期与启动模式的更多相关文章

  1. Android开发艺术探索(一)——Activity的生命周期和启动模式

    Activity的生命周期和启动模式 生命周期有? 1.典型情况下的生命周期—>指有用户参与的情况下,Activity所经过的生命周期改变 2.异常情况下的生命周期—>指Activity被 ...

  2. 《Android开发艺术探索》读书笔记 (1) 第1章 Activity的生命周期和启动模式

    第1章 Activity的生命周期和启动模式 1.1 Activity生命周期全面分析 1.1.1 典型情况下生命周期分析(1)一般情况下,当当前Activity从不可见重新变为可见状态时,onRes ...

  3. Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式

    Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...

  4. Activity的生命周期和启动模式

    Activity的生命周期分析 典型情况下的生命周期.是指在用户参与的情况下,Activity所经过的生命周期的改变. 异常情况下的生命周期.是指Activity被系统回收或者由于当前设备的Confi ...

  5. 一、Activity的生命周期和启动模式

    1.Activity的生命周期 1.1.典型情况下的生命周期 在有用户参与的情况下,Activity所经过的生命周期的改变. Activity会经历如下生命周期: onCreate-onRestart ...

  6. 第一章:Activity的生命周期和启动模式

    Activity是Android中四大组件之首,所以需要重视,尤其是启动方式,在AndroidManifest.xml中的注册信息 (一)Activity的生命周期 1.1.1 正常情况下的生命周期 ...

  7. 6) 十分钟学会android--Activity的生命周期之启动与销毁

    当用户导航.退出和返回您的应用时,应用中的 Activity 实例将在其生命周期中转换不同状态. 例如,当您的Activity初次开始时,它将出现在系统前台并接收用户焦点. 在这个过程中,Androi ...

  8. android activity的生命周期和启动模式

    activity是android开发的基本中的基本每一个项目都会有activity.activity有自己的生命周期,在网上有很多博客和资料,在这里我也只是印证一下. 一个activity: 在打开a ...

  9. 复习篇(一)Activity的生命周期和启动模式

    (一)关于<intent-filter>中的<data> 当设置<data>过滤器的时候,使用intent的时候必须要设置响应的匹配,否则无法匹配成功.不过不设置则 ...

随机推荐

  1. Java Se:Java Security

    Java API中有很多都使用了SecurityManager,这到底是什么玩意?最近看公司的产品的源码,也有不少SecurityManager.AccessControlContext等相关的代码, ...

  2. Sql Server之旅——第十站 看看DML操作对索引的影响

    我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 ...

  3. spring 依赖注入(IOC DI)

    依赖注入(IOC DI) 依赖注入的两种方式: 1. set注入 Spring要求使用set注入方式的时候,Bean需要提供一个无参数的构造方法.并提供一个属性的setter方法.例如: packag ...

  4. oracle数据泵示例

    主要的导出示例: 1.导出指定表空间: expdp system/xxx DIRECTORY=dump_dir tableapace=xxx dumpfile=xxx_%DATE:~0,4%%DATE ...

  5. JavaScript目录菜单滚动反显组件的实现

    JavaScript目录菜单滚动反显组件,有以下两个特点 每个导航菜单项(nav)对应页面一个内容区域(content) 滚动页面到特定内容区域(content)时,对应的菜单会自动切换,一般会添加一 ...

  6. linux开机自动连接无线网络

           1.右击无线网络图标的“编辑连接”. 2.在“无线”选项卡里,选择“编辑”. 3.在“无线安全性”选项卡里,输入无线密匙,并选中左下角的“对所有用户可      用”的选项点击应用,会提 ...

  7. .net 操作sftp服务器

    因为项目的需要,整理了一段C#操作sftp的方法. 依赖的第三方类库名称为:SharpSSH 1.1.1.13. 代码如下: 1: using System; 2: using System.Coll ...

  8. iTOP-4412嵌入式开发板ioremap控制GPIO寄存器

    转自迅为电子技术论坛:http://bbs.topeetboard.com GPIO 的寄存器通过 ioremap函数转换之后,可以通过直接控制虚拟地址来控制物理地址(寄存器的实际地址),这样就实现 ...

  9. 贤者时间太久了么?--MySQL继续玩

    hi 给自己放了大概三天的假,没有一点点防备,没有一点点准备,无意的 是不是贤者时间过不去了我不知道啊...继续看东西吧 1.MySQL -----运算符和函数----- 字符函数,数值运算符,比较运 ...

  10. Buffer Overflow Study

    -- These days I learned and studied buffer overflow. I like to write on the paper and it can keep sy ...