正常状况下的Activity生命周期以下图所示(来自Android Developer):3d
当资源相关的系统配置变动时(好比设备屏幕方向改变,键盘可见性变化),会致使Activity的销毁与重建。某些系统配置变动时,系统会根据最新配置从新为应用加载适合于当前配置的资源,这些系统配置就是资源相关的系统配置。此时在销毁Activity前会调用onSaveInstance()方法已保存当前的状态信息,这个方法会在onStop()前被调用,但与onPause()的时序关系不肯定。当Activity被从新建立后,onRestoreInstanceState()方法会被调用以恢复以前保存的状态信息,这个方法具体的调用时机是在onStart()以后。blog
onSaveInstanceState()方法只有在被销毁的Activity随后会从新被建立时才会被调用,主要有以下两种状况:生命周期
一个就是咱们上面提到的资源相关的系统配置变动时;内存
另外一个状况就是系统内存不足致使低优先级的Activity被杀死,这种状况下系统在销毁Activity时会调用onSaveInstanceState()方法,而且随后当被杀死的Activity从新启动时,onRestoreInstanceState()方法会被回调。ci
在介绍Activity前,咱们先简单地介绍一下任务栈(back stack)的概念。假设咱们从桌面首次启动了某个App,系统会开启一个新的任务栈并把该App的MainActivity(设为Activity1)加入这个任务栈中,若以后咱们在新启动的App中又打开了Activity 二、Activity 3,则Activity 2和Activity 3也会被依次压入这个任务栈中。因而如今任务栈的栈顶就是Activity 3了,咱们与之交互的Activity始终是当前任务栈栈顶的Activity。如今咱们点击了Back键,则Activity 3会被弹出任务栈,当前栈顶的Activity即变为了Activity 2,咱们开始与Activity 2进行交互。资源
以上过程可用下图来描述:开发
(1)standard:标准模式(默认)it
以standard模式启动的Activity会被放入启动它的那个Activity所在的任务栈(Back Stack)中。在咱们调用Context.startActivity方法去启动standard模式的Activity时会报错, 由于ApplicationContext并无关联一个任务栈,解决方案是为待启动Activity指定FLAG_ACTIVITY_NEW_TASK标记位,此时会新键一个任务栈,并把刚启动的Activity放入其中,这种状况下被启动Activity实际上以singleTask模式启动。以standard模式启动Activity的话,若屡次启动会建立多个Activity实例。io
(2)singleTop:栈顶复用模式class
若待启动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就会去本该属于它的地方。
(1)Android Developer
(2)《Android开发艺术探索》