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

Activity的生命周期

一.生命周期分类

1.典型生命周期:

 在有用户参与的情况下,正常完整的生命周期

2.异常生命周期:

(1).系统内存不足,Activity被系统回收

 (2).当前设备的Configuration改变,导致Activity销毁重建

二.典型情况下的生命周期

1.onCreate

2.onRestart

 用户行为导致Activity从不可见到可见,会被调用

3.onStart

 可见,不可交互

4.onResume

 可见,可交互

5.onPause

不可太耗时,执行完成后,才会执行新开启Activity的onResume

6.onStop

 可做轻微重量级回收,不可太耗时

7.onDestory

三.典型情况下生命周期的补充说明

现有两个Activity,分别为A和B

1.首次启动A

onCreate -> onStart -> onResume

2.启动B或者按下home键

onPause -> onStop(若B透明,则不走此方法)

3.再次回到A

onRestart -> onStart -> onResume

4.按bask键回退(销毁)

onPause -> onStop -> onDestory

5.由A开启B,A的onPause和B的onResume执行顺序

(A)onPause -> (B)onCreate,onStart,onResume -> (A)onStop

故不能在A的onPause中执行耗时操作,尽量放于onStop

6.整个生命周期中,方法的成对分析

(1).onCreate和onDestory

标识Activity的创建和销毁,只能调用一次

(2).onStart和onStop

标识Activity是否可见,随着用户的操作或者设备屏幕的点亮或熄灭,可能会被调用多次

(3).onResume和onPause

标识Activity是否在前台(是否可交互),随着用户的操作或者设备屏幕的点亮或熄灭,可能会被调用多次

四.异常情况下生命周期补充说明

1.系统内存不足,导致低优先级的Activity被杀死

(1).Activity按照优先级的分类

前台Activity,正在和用户交互,最高

可见但非前台Activity,比如Activity中弹出一个对话框,次之

后台Activity,已被暂停的Activity,比如执行了onStop,最低

(2).当系统内存不足时,则会按照优先级从低到高杀死Activity所在进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来恢复数据

(3).若一个进行中没有四大组件在运行,则该进程很快将被杀死,若一些后台工作不适合脱离四大组件而独自运行在后台中,可将该后台工作放入Service中从而保证进程有一定优先级,不会轻易被系统杀死

2.资源相关的系统配置发生改变导致Activity被杀死并重新创建

(1).默认情况下,若Activity不做特殊处理,当系统配置发生改变,Activity就会被杀死并重建

(2).其onPause,onStop,onDestory会被调用

(3).由于Activity在异常情况下被终止并且有可能重新显示的情况下,系统会调用onSaveInstanceState来保存当前Activity的状态,onSaveInstanceState一定会在onStop之前调用,可能会在onPause之前或之后,正常情况下,系统不会调用onSaveInstanceState

(4).Activity被重建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate,故可通过onRestoreInstanceState和onCreate方法来判断Activity是否被重建,并可取出之前保存的参数并恢复,onRestoreInstanceState在onStart之后被调用

(5).Activity重建后,调用onRestoreInstanceState和onCreate的区别

onRestoreInstanceState一旦被调用,其参数Bundle savedInstanceState一定是有值的,不需要额外判空,官方推荐此方法来恢复数据

onCreate被调用可能是正常启动,也可能是异常下启动,故其参数Bundle savedInstanceState可能为null,需要判空

(6).保存和恢复View的层次结构,系统的工作流程

首先,Activity被意外终止,Activity会调用onSaveInstanceState来保存数据

然后Activity会委托Window来保存数据

接着Window再委托它上面的顶层容器来保存数据,该顶层容器是一个ViewGroup,一般来说是DecorView

最后,顶层容器再去一一通知它的子元素来保存数据

五.系统配置发生改变后,如何避免Activity的重新创建

1.常见的configChanges属性

keyboard 键盘类型发生改变,比如使用了外接键盘

keyboardHidden 键盘的可访问性发生改变,比如调出了键盘

orientation 屏幕方向发生改变,比如旋转手机屏幕

screenSize 屏幕尺寸发生改变,比如旋转手机屏幕,API > 13时,才会导致Activity重启

2.可以给Activity在清单文件中指定configChanges属性

android:configChanges="orientation|screenSize"

此后Activity不会被重建,也不会调用onSaveInstanceState和onRestoreInstanceState来保存和恢复数据,而是调用onConfigurationChanged方法

Activity的启动模式

一.启动模式的4种类型

1.standard 标准模式

(1).每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在

(2).标准模式下,被启动的Activity位于启动Activity的任务栈中,比如A启动B(标准模式),则B进入到A所在的栈中

2.singleTop 栈顶复用模式

(1).若新Activity位于栈顶,那此Activity不会重建,但onNewIntent方法会被调用,此时该Activity的onCreate,onStart不会被调用

(2).若新Activity实例已存在但不是位于栈顶,则该Activity会重建

(3).假设目前栈内Activity为ABCD,再次开启D:

若D为standard,则为ABCDD;

若D为singleTop,则为ABCD

3.singleTask 栈内复用模式

(1).若Activity在栈中已存在,多次启动该Activity,都不会重新创建实例,但onNewIntent方法会被调用

(2).什么是Activity所需的任务栈?

a.和一个参数TaskAffinity有关,可翻译为任务相关性,该参数标识了一个Activity所需要的任务栈的名字

b.默认情况下,所有Activity所需要的任务栈的名字为应用的包名

c.可以为每个Activity都单独指定TaskAffinity属性,该属性值必须不能和包名相同,否则相当于没有指定

d.可在清单文件中指出,则Activity会运行在这个名字即com.xiaozai.cn的任务栈中

android:TaskAffinity="com.xiaozai.cn"

f. TaskAffinity属性主要和singleTask启动模式配合使用,其他情况下没有意义

(3).开启singleTask模式Activity A的流程梳理:


一.Activity的生命周期和启动模式_第1张图片
singleTask模式启动流程图

(4).举例说明

a.当前任务栈为S1,内有ABC三个Activity,D为singleTask,且所需任务栈为S2,由于S2和D的实例均不存在,故先创建任务栈S2,再创建D的实例,并压入S2

b.当前任务栈为S1,内有ABC三个Activity,D为singleTask,且且所需任务栈为S1,由于S1已存在,故会创建D的实例,并将其压入S1

c.当前任务栈为S1,内有ADBC四个Activity,D为singleTask,且且所需任务栈为S1,由于S1已存在,根据栈内复用原则,此时不会重建D的实例,而是把D调到栈顶,并把D上面的BC清除出栈,同时回调onNewIntent方法,最终栈S1中为AD


一.Activity的生命周期和启动模式_第2张图片
singleTask模式启动流程图2

4.singleInstance 单一实例模式

除了具备singleTask模式所有的特性外,还加强一点,就是singleInstance模式的Activity,只能单独的位于一个任务栈中,若A为singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A独自在这个任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个任务栈被系统销毁了

二.如何为Activity指定启动模式?

1.分类

(1).通过AndroidMenifest为Activity指定启动模式

android:launchMode="singleTask"

(2).通过在Intent中设置标志位为Activity指定启动模式

Intent intent = new Intent(MainActivity.this,SecondActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

2.区别

(1).优先级 

第二种优先级高于第一种,二者同时存在,以第二种为准

(2).限定范围

第一种无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识

第二种无法为Activity指定singleInstance模式

三.Activity的Flags

1.FLAG_ACTIVITY_NEW_TASK

为Activity指定singleTask启动模式,和在清单文件中指定效果一样

2.FLAG_ACTIVITY_SINGLE_TOP

为Activity指定singleTop启动模式,和在清单文件中指定效果一样

3.FLAG_ACTIVITY_CLEAR_TOP

具有此标记的Activity,当前启动时,在同一个任务栈中所有位于它上面的Activity都要出栈.

此模式一般需要和FLAG_ACTIVITY_NEW_TASK配合使用

四.IntentFilter的匹配规则

你可能感兴趣的:(一.Activity的生命周期和启动模式)