Rickwan's Blog

《每周一记》Android之Activity的生命周期和启动模式

为之于未有,治之于未乱。

Activity作为Android四大组件之首,它的生命周期和启动模式在平时的开发中,重要而又常见,很多同学认为Activity的生命周期太简单而忽略了它的重要性,熟练的掌握相关知识,对于Activity的灵活运用会有很大的帮助。

1、Activity的生命周期

详情:官方地址

Tips:

  • Activity采用透明主题时,不会回调onStop
  • 旋转屏幕使Activity不会重新创建的方法:
    android:configChanges=”orientation|keyboardHidden|screenSize”

2、Activity的启动模式

2.1 Activity的LaunchMode

有时候为了满足项目特殊需求,我们就必须使用Activity的启动模式,下面将简单的介绍一下四种启动模式:standard、singleTop、singleTask、singleInstance。

这些模式分为两大类,“standard”和“singleTop”Activity 为一类,“singleTask”和“singleInstance”为另一类。前两者启动模式的Activity可以被实例化多次。

  • standard:标准模式
    每次启动一个Activity都会创建一个新的实例
  • singleTop:栈顶复用模式
    如果目标任务的顶部已存在一个Activity实例则系统会通过调用该实例的onNewIntent()方法向其传送Intent,而不是创建新的Activity实例。
  • singleTask:栈内复用模式
    系统在新任务的根位置创建Activity并向其传送Intent。不过,如果已存在一个Activity实例,则系统会通过调用该实例的onNewIntent()方法向其传送Intent,而不是创建新的Activity实例,同时会将位于该实例顶部的其他实例全部移除出栈。
    此处将受TaskAffinity属性影响(用于指定Activity所关联的Task),系统将查询是否有该Activity需要的任务栈,如果不存在,就会重新创建一个任务栈,然后创建Activity的实例;如果该任务栈已存在,则继续查询是否已存在该Activity的实例,如果不存在,则创建实例并放入栈中,如果存在,则将该实例顶部的其他实例全部推出栈。

  • singleInstance:单例模式
    与“singleTask””相同,只是系统不会将任何其他Activity启动到包含该实例的任务中。该Activity始终是其任务唯一仅有的成员。

2.2 Activity的Flags

Activity的Flags有很多,详情请查看官方文档,这里介绍几种比较常用的标记位。标记位的作用有很多,有的可以设定Activity的启动模式。

  • FLAG_ACTIVITY_NEW_TASK:
    为Activity指定“singleTask”启动模式
  • FLAG_ACTIVITY_SINGLE_TOP:
    相当于LauchMode中的singleTop。
  • FLAG_ACTIVITY_CLEAR_TOP:
    在同一个任务栈中所有位于它上面的Activity都要出栈。这个标记位一般都singleTask启动模式一起出现,在这种情况下,被动的Activity的实例如果已经存在,系统就会调用它的onNewIntent。如果被启动的Activity采用standard启动模式,那么它连同它之上的Activity都要出栈,系统会创建新的实例并放入栈顶。
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:
    具有这个标记位的Activity不会出现在历史Activity的列表中,如果调出的Activtivity只是一个功能片段,并没有实际的意义,此时长按Home键调出最近使用过的程序类表中,将不会出现此Activity。
  • FLAG_ACTIVITY_NO_HISTORY:
    使用这个FLAG启动的Activity,一旦退出,它不会存在于栈中,比如说,原来是A,B,C这个时候在C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。
2.3 LaunchMode和Flags的运用

设置Activity启动模式的两种方法:

  • 通过在AndroidMenifest.xml中设置:

    1
    2
    3
    4
    <activity
    android:name=".ui.activity.MainActivity"
    android:screenOrientation="portrait"
    android:launchMode="singleTask"/>
  • 通过Intent设置标志位

    1
    2
    3
    Intent intent = new Intent(this,MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

以上两种方式都可以为Activity设置启动模式,当两者同时存在时,将以第二种为准,第一种方式无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识,而第二种则无法为Activity指定singleInstance模式。