Activity的生命周期和启动模式

1.生命周期

1.1典型情况下的生命周期
Activity的生命周期和启动模式_第1张图片
lifeCircle.png

  1. 在ActivityA上启动ActivityB:
    A:onPause()
    B:onCreate()
    B:onStart()
    B:onResume()
    A:onStop()
  2. 用户按下Back键:
    onPause()
    onStop()
    onDestroy()

1.2异常情况下的生命周期

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

  1. 默认情况下,当系统设置发生改变后,Activity就会被销毁并重新创建:
    销毁:
    onPause()+onSaveInstanceState() 这两者没有时序关系,同时onSaveInstanceState()只会在异常终止下调用
    onStop()
    onDestroy()
    重新创建:
    onCreate()
    onStart()
    onRestoreIntanceState()
    onResume()
  2. 恢复数据可以选择在onCreate()和onRestoreInstanceState()。区别在于后者一旦被调用参数 Bundle savedInstacneState一定有值

1.2.2资源不足导致低优先级的Activity被杀死

Activity优先级:

  1. 前台Activity——正在和用户交互的Activity,优先级最高
  2. 可见但非前台Activity——比如Activity中弹出了一个对话框,导致activity可见但是位于后台无法和用户交互。
  3. 后台Activity——已经被暂停的Activity比如执行了onStop(),优先级最低

1.3 系统设置发生改变后,不重新创建Activity

在指定Activity的注册xml中设置configChanges属性指定那些设置发生变化后不重新创建即可,但是会导致调用onConfigurationChaged(Configration newConfig)

2.启动模式

2.1 LaunchMode

Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack)。在默认情况下,我们新启动了一个活动,它会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish()方法去销毁一个活动时,处于栈顶的活动就会出栈。默认情况下一个Activity所需要的任务栈的名字为应用的包名

  1. standard:标准模式,系统默认模式。每次启动一个活动都会重新创建一个新的实例,不管这个实例是否已经存在。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下谁启动了这个Activity,这个Activity就运行在启动它的那个Activity所在的栈中。

  2. singleTop:栈顶复用模式。在这种模式下,如果要启动的Activity已经存在于栈顶,此Activity就不会被重新创建,onCreate()、onStart()不会被调用,但是onNewIntent方法会被回调然后调用onResume(),通过此方法我们可以取出当前请求的信息。如果不位于栈顶,则会重新创建。

  3. singleTask:栈内复用。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,只是回调onNewIntent()。具体一点,当一个Activity A以singleTask模式请求启动后,系统首先会去寻找有没有A所需要的任务栈,没有则创建这个任务栈并且创建一个A的实例置于栈顶。有则去看这个任务栈中是否已经存在A的实例,存在则把之前的Activity都出栈,这样A的实例就处于栈顶了并且调用onNewIntent(),没有则创建一个实例并置于栈顶。

  4. singleInstance:单实例模式。这是一种加强的singleTask模式,这种模式的Activity只能单独的位于一个任务栈中。

Activity的TaskAffinity属性:标识了一个Activity所需要的任务栈的名字。

TaskAffinity+singleTask:待启动的Activity会运行在名字和TaskAffinity值相同的任务栈中

TaskAffinity+allowTaskReparenting(活动属性):当allowTaskReparenting = "true"时,从应用A启动应用B的活动C,然后启动B,C会直接从A的任务栈转移到B的任务栈的栈顶。

如何给Activity指定启动模式?

  1. 在Menifest中注册Activity时设置它的launchMode属性 例如:android:launchMode="singleTask"
  2. 在Intent中设置标志位来为Activity指定启动模式

两种设置启动模式的区别?

  1. 第二种的优先级高于第一种,当两者同时存在以第二种为准。
  2. 限定范围不同,比如第一种方式无法直接为Activity设置FLAG_ACTIVITY_CLEAR_TOP,而第二种无法指定singleInstance.

2.2 Activity的Flags

比较常用:

  1. FLAG_ACTIVITY_NEW_TASK:等同singleTask
  2. FLAG_ACTIVITY_SINGLE_TOP:等同singleTop
  3. FLAG_ACTIVITY_CLEAR_TOP:一般和singleTask一起出现;如果被启动的Activity采用standard模式启动,那么它连同它之上的Activity都要出栈,系统会创建新的Activity实例并放入栈顶。
  4. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:不会出现在历史Activity列表中

3.IntentFilter的匹配规则

我们知道,活动的启动有两种方式:

  1. 显式调用
  2. 隐式调用

原则上这两种调用方式不应该共存,如果共存以显式调用为主。

隐式调用需要Intent能够匹配目标组件的IntentFilter中设置的过滤信息。


   
      
      
      
   

action category data 均可以有多个
intent-filter 也可以有多个

3.1 action的匹配规则

action是一个字符串,系统预定义了一些action,同时我们也可以自己在应用中自己定义自己的action。对于intent-filter中的多个action,只要Intent中的action有一个和其中的一个完全匹配,则action匹配成功。总结一下,action的匹配要求Intent中的action存在且必须和过滤规则中的一个action完全相同。

3.2 category的匹配规则

category是一个字符串,系统预定义了一些category,同时我们也可以自己在应用中自己定义自己的category。

  1. Intent中如果没有category,则匹配成功,因为会自动匹配默认的那个category
  2. Intent中有一个或者多个category,则出现的每个category都必须在intent-filter中有完全匹配的。

3.3 data的匹配规则

 ////资源类型

Intent中必须有data,且必须匹配一个intent-filter中的data

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