启动模式

在启动一个应用时系统会默认创建一个任务栈(stack)来管理Activity,它遵循着先进后出,后进先出的原则,由于任务栈的这种特性会在一些时候造成资源浪费,例如:有时候多次启动相同的Activity(比如多数APP中都会有的主页Activity)那么这时就会在任务栈中创建多个不必要的实例。而启动模式就是用来修改这种默认行为。

想要更改启动的模式,必须在注册文件(AndroidManifest文件)中为Activity添加LaunchMode属性:

1
2
3
4
5
6
7
<activity android:name=".MainActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

可选模式有一下几种:

Standard(默认)

标准启动模式,也就是默认的后进先出方式,每次启动会重新创建一个新的实例加入当前Acitivity所在的到栈中,也就是A启动了B,B就会加入到A的任务栈,多次启动,就是多个B加入到A的栈中。

Standard模式

因此如果用ApplicationContext去启动一个Activity就会报错,因为Application没有任务栈:

1526194185722

这个时候就需要添加一个新建任务栈的Flag: FLAG_ACTIVITY_NEW_TASK

SingleTop

栈顶复用模式,在这种模式下,如果入栈的Activity与当前栈的栈顶Activity相同,就不会去创建一个新的实例,而是沿用已存在的Activity。此时已存在的Activity不会调用onCreateonStart生命周期,而是直接进入onResume,同时会调用onNewIntent周期方法

singleTop模式

SingleTask

栈内复用模式,在这个模式下分为两步流程,第一步,寻找Activity所指定的任务栈是否存在,不存在就创建一个新的任务栈。第二步,在指定的任务栈内寻找是否存在相同的Activity,不存在就创建一个实例,存在就进行复用,将在它之上的Activity弹出(SingleTask默认具有clearTop行为)让其处于栈顶,同时这个复用的Activity不会调用onCreateonStart生命周期,直接调用onResume,也会调用onNewIntent

1526200621379

指定任务栈需要在注册文件中为Activity添加上taskAffinity属性,这个属性相当于任务栈的别名,是可以重复的,只有系统分配的id才是唯一的。默认这个属性的值为应用包名,:

1
2
3
4
5
6
7
8
<activity android:name=".MainActivity"
android:taskAffinity=".Task_B" //这里需要以点开头
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

SingleInstance

单实例模式,这个模式属于特殊的SingleTask模式。在该模式下,Activity启动时无论怎样,都会重新创建一个新的任务栈,同时添加这个Activity的实例,后续的Activity要么添加到之前的任务栈,要么添加到新建的任务栈,总之都不会再添加到这个任务栈中(taskAffinity相同也会新建一个任务栈)

1526218109562

关于任务栈,还分为前台和后台,前台即包含正在与用户交互的Activity所在的任务栈,其他的都是后台任务栈

生命周期

Activity之间都是交替运行,为了感知当前Activity的状态,Android提供了一套生命周期回调方法,以此让开发者更好的管理Activity

正常的生命周期

在正常的生命周期中,Activity会经历从创建到销毁一系列有序的生命周期回调。

onCreate

创建时,此时可以为当前的Activity设置布局文件,添加数据等,在这里需要注意的是,这时的Activity 还没有开始测量和绘制工作,有些属性现阶段是无法获取的(比如非固定的View的宽高)。

onRestart

重启时,这个方法在创建一个Activity时不会调用,它的调用的时机是在从后台过度到前台时调用,比如在A跳转到B,再从B返回时调用。按Home键之后再次进入时。同时它会在onStart之前调用

onStart

启动时,现阶段的Activity处于已经创建完毕,但是还没有展示到用户面前的状态,即不可见状态

onResume

运行时,表示Activity已经处于可见状态,可以与用户进行交互了。

onPause

停止进行时,在即将离开当前Activity时调用,这时可以做一些不会太耗时的工作(因为这会影响到新的Activity的创建),比如保存用户数据,停止动画等。

onStop

停止时,Activity这时已经处于后台,可以跟进一步回收工作。也是不能太耗时

onDestroy

销毁时,表示Activity即将被销毁,在这里一般会做一些会做一些最终的资源释放

Activity的生命周期

异常的生命周期

异常的生命周期是指,Activity被系统回收或者因为系统的配置被更改了从而导致的销毁重建。

onSaveInstance

Activity因为上述情况进行进行销毁重建时,在onStop之前调用。它会带有一个Bundle类型的参数,可以添加一些轻量的可序列化的数据保存起来,以供之后恢复。

onRestoreInstanceState

与上面onSaveInstance方法对应的方法,会在onStart之后调用,它的参数就是就是之前保存的Bundle类型的变量。这个变脸也会传给onCreate方法。

其他的一些生命周期

onNewInstance

这个方法会在Activity复用时调用,它接受一个Intent类型的参数。这个Intent的参数就是新的Intent变量。如果当前的Activity需要根据传入的值做一些判断,刚好他又是一个需要复用的Activity,就可以在这个 方法里面进行操作

onConfigurationChanged

这个方法会在系统的一些配置更改时调用(需要在注册文件的configChanges属性中添加要接受的配置更改),例如旋转屏幕,字体大小更改等等:

1526225421891

它会接受一个Configuration类型的参数,它表示最新的设备配置信息。