Activity生命周期
、
(1)针对一个特定的Activity,第一次启动:onCreate -> onStart -> onResume。
(2)当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause -> onStop。这里有一种特俗情况,如果新Activity采用了透明主题,那么当前Activity不会回调onStop。
(3)当用户再次回到原Activity时,回调如下:onRestart ->
onStart -> onResume。
(4)当用户按back键回退时,回调如下:onPause -> onStop -> onDestory。
(5)从整个生命周期来说,onCreate和onDestroy来配对的,分别标识着Activity的创建和销毁,并且只可能有一次调用。从Activity是否可见来说,onStart和onStop是配对,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法可能被调用多次。从Activity是否在前台来说,onResume和onPause是配对的,随着用户操作或者设备屏幕的点亮和熄灭这两个方法可能被调用多次。
(6)当启动一个Activity的时候,旧Activity的onPause会先执行,然后才会启动新的Activity。因此不能在onPause和onStop中做重量级的操作,尤其是onPause。
异常情况下的生命周期分析。
情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建
举个例子,旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以阻止系统重新创建我们的Activity。
(1)这个时候系统会自动帮我们调用onSaveInstanceState来保存当前Activity的状态。这个方法的调用时机是在onStop之前,它和onPause没有既定的时序关系,既可以在之前,也可以在之后。
(2)当Activity被重新创建后,系统会调用onRestoreInstance
State,并且帮Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和
onCreate方法。从时序上来说,调用在onStart之后。
这两个方法只有在Activity异常终止的情况下才会被调用,正常情况下是不会被调用的。同时,在这两个方法中,系统自动为我们做了一定的恢复工作。恢复过程是从Activity ->
Window ->顶级View ->子View。
情况2:资源内存不足导致低优先级的Activity被杀死。
Activity的优先级从高到低,可以分为如下三种:
(1)前台Activity——正在和用户交互的Activity,优先级最高。
(2)可见但非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法与用户直接交互。
(3)后台Activity——以及被暂停的Activity,比如执行了onStop,优先级最低。
当系统内存不足时,系统就会按照上述优先级去杀死目标的Activity所在的进程,并在后续通过onSaveInstanceState和
onRestoreInstanceState来存储和恢复数据。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。
如果当某项内容发生改变后,我们不想系统重新创建Activity,就可以给Activity指定configChanges属性。比如屏幕旋转:
android:configChanges:”orientation”。
调用后,屏幕旋转,Activity不会重新创建,并且也不会调用onSaveInstanceState和onRestoreInstanceState来存储数据,取而代之的是系统调用Activity的onConfigurationChanged方法,这个时候我们就可以做一些特殊的处理了。
Activity的启动模式(LaunchMode)
Activity启动后是放入任务栈中,任务栈是一种“后进先出”的栈结构,每按一个back键就有一个Activity出栈,直到栈空为止,当栈中无任何Activity的时候,任务栈就会被回收。
Activity目前有四种启动模式:standard、singleTop、single
Task和singleInstance。
(1)standard:标准模式,这也是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。比如A启动了B
(B是标准模式),那么B就会进入到A所在的栈中。
(2)singleTop:栈顶复用模式。在这种模式下,如果新Activit
y已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时他的onNewIntent方法会被回调,通过此方法的参数我们可以去除当前请求的信息。这个Activity的onCreate、onStart不会被系统调用,因为他并没有发生改变。如果不是位于栈顶,仍然会重新创建。
(3)singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Act
Ivity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent。
(4)singleInstance:单实例模式,这是一种加强的singleTask模式,它除了具有singleTask模式的所有特性外,此种模式的Activity只能单独地位于一个任务栈中。比如A是singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A独自在这个新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了。
有两种方法为Activity指定启动模式:
(1)通过AndroidManifest中设置属性
(2)通过Intent设置标志位来为Activity指定启动模式
这两种,第二种的优先级高于第一种,同时存在时以第二种为准。其次,第一种无法为Activity指定FLAG_ACTIVITY
_CLEAR_TOP标识,而第二种方法为Activity指定singleInstanc
e模式。
TaskAffinity
默认情况下,所有Activity所需的任务栈的名字为应用的包名。当然我们可以为每个Activity指定TaskAffinity属性,这个参数表示了一个Activity所需要的任务栈的名字,这个属性不能和报名相同,否则就相当于没有指定。
TaskAffinity属性主要和singleTask启动模式或者allowTas
kReparenting属性配对使用,在其他情况下没有意义。任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
当TaskAffinity和allowTaskReparenting相结合的时候,这种情况比较复杂,会产生特殊的效果。当一个应用A启动了应用B的某个Activity后,如果这个Activity的allowTaskReparen
ting属性为true的话,那么当应用B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈中。
Activity的Flags
Activity的Flags有很多,这里主要分析一些比较常用的标记位。标记位的作用很多,有的标记位可以设定Activity的启动模式;还有的标记位可以影响Activity的运行状态。下面是比较常见的几个标记位:
FLAG_ACTIVITY_NEW_TASK
这个标记位的作用是为Activity指定“singleTask”启动模式。
FLAG_ACTIVITY_SINGLE_TOP
singleTop启动模式
FLAG_ACTIVITY_CLEAR_TOP
具有此标记的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。singleTask默认具有此效果。