Activity启动模式

幻昼 2020年03月16日 469次浏览

当我们多次启动同一个Activity时,系统会创建多个实例,并把它们按照先进后出的原则一一放入任务栈中,当我们按back键时,就会有一个activity从任务栈顶移除,重复下去,直到任务栈为空,系统就会回收这个任务栈。

但是这样以来,系统多次启动同一个Activity时就会重复创建多个实例,这种做法显然不合理,为了能够优化这个问题,Android提供四种启动模式来修改系统这一默认行为。

要从四个角度理解Activity的启动模式

从操作系统角度

Activity代码属于Application,但是Task属于Android操作系统。

操作系统管理的是一个个的Task,然后调控Task里面的Activity,不管来自哪个应用。

Task_OS

查看操作系统中Task的Activity情况

adb shell dumpsys activity activities | grep Stack

从用户角度

一个用户可以用什么形式进去到Activity里面呢?

新建

  1. 从系统通知

    系统通知

  2. 通过第三方应用

    third—app

恢复

  1. Navigation 最近任务栏

    navigation

  2. Back按键

    back

Laucher启动

Task已经存在、不存在两种情况

从开发者角度

Activity与Fragment

Fragment的生命周期依赖Activity,可以看成片段,依赖Activity这个容器。

Fragment

Activity生命周期

基本生命周期

Activity
Activity

Activity间启动

multi—Activity

生命周期联系

onCreate和onStart之间有什么区别?

  1. 可见与不可见的区别。前者不可见,后者可见。
  2. 执行次数的区别。onCreate方法只在Activity创建时执行一次,而onStart方法在Activity的切换以及按Home键返回桌面再切回应用的过程中被多次调用。因此Bundle数据的恢复在onStart中进行比onCreate中执行更合适。
  3. onCreate能做的事onStart其实都能做,但是onstart能做的事onCreate却未必适合做。如前文所说的,setContentView和资源初始化在两者都能做,然而想动画的初始化在onStart中做比较好。

onStart方法和onResume方法有什么区别?

  1. 是否在前台。onStart方法中Activity可见但不在前台,不可交互,而在onResume中在前台。
  2. 职责不同,onStart方法中主要还是进行初始化工作,而onResume方法,根据官方的建议,可以做开启动画和独占设备的操作。

onPause方法和onStop方法有什么区别?

  1. 是否可见。onPause时Activity可见,onStop时Activity不可见,但Activity对象还在内存中。
  2. 在系统内存不足的时候可能不会执行onStop方法,因此程序状态的保存、独占设备和动画的关闭、以及一些数据的保存最好在onPause中进行,但要注意不能太耗时。

onStop方法和onDestroy方法有什么区别?

  1. onStop阶段Activity还没有被销毁,对象还在内存中,此时可以通过切换Activity再次回到该Activity,而onDestroy阶段Acivity被销毁

onNewIntent

  1. 只对singleTop,singleTask,singleInstance有效,因为standard每次都是新建,所以不存在onNewIntent;
  2. 只对startActivity有效,对于从Navigation切换回来的恢复无效;

onNewIntent

启动模式

standard-标准模式

每个Task可以创建多个实例

每次启动一个Activity都会重写创建一个新的实例,并向其传送 Intent。谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。

配置形式

<activity android:name=".standard.StandardActivity" android:launchMode="standard" > 

singleTop-栈顶复用模式

每个Task的顶部只能创建一个实例

一个singleTop Activity 的实例可以无限多,唯一的区别是如果在栈顶已经有一个相同类型的Activity实例,Intent不会再创建一个Activity,而是通过onNewIntent()被发送到现有的Activity。

singleTop

singleTask-栈内复用模式

只能在一个Task中创建一个实例

这是一种单实例模式,在这种模式下,只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,和 singleTop一样,系统也会回调其 onNewIntent。

当一个具有 singleTask 模式的Activity请求启动后,比如 Activity A,系统首先会寻找是否存在 A 想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建 A 的实例后把 A 放到栈中。如果存在 A 所需的任务栈,这时要看 A 是否在栈中有实例存在,如果有实例存在,那么系统就会把 A 调到栈顶并调用它的 onNewIntent 方法,如果实例不存在,就创建 A 的实例并把 A 压入栈中 。

singleTask

singleInstance-单实例模式

只能创建一个实例,并且独占一个task

与 singleTask 相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。也就是有此种模式的 Activity 只能单独地位于一个任务栈中

从架构师、产品经理角度

singleTop

适合启动同类型的 Activity,例如:

  1. 接收通知启动的内容显示页面
  2. 耗时操作返回页面
  3. 登录页面

singleTask

适合作为程序入口,例如:

  1. WebView页面
  2. 扫一扫页面
  3. 确认订单界面
  4. 付款界面

singleInstance

适合需要与程序分离开的页面,例如:

  1. 闹铃的响铃界面
  2. 来电页面
  3. 锁屏页