前言:作为一个页面单元,Activity在Android App开发中承担着显示页面,加载UI元素,提供应用与用户交互窗口的重要作用。那么,从创建,显示,直到关闭,Activity经历了怎样的一个过程?系统又是如何对Activity进行管理的?下面让我们来了解一下。
Activity的生命周期,描述了一个Activity从创建到销毁的过程中,不同阶段所调用的生命周期函数。了解Activity的生命周期,使我们在开发中能够根据实际情况,在合适的时机调用合适的代码。Activity的生命周期函数有:
(1)onCreate():当创建一个Activity时默认会生成这个函数。onCreate()在Activity第一次创建的时候被调用,通常在这个函数中完成一些初始化的操作,如设置关联布局、查找UI元素,初始化视图、绑定事件等。
(2)onStart():在onCreate()调用之后被调用,此时Activity还处于不可见状态。即在Activity创建完成但仍未显示的时候被调用。
(3)onResume():在Activity变为可见的时候被调用。执行完此函数后,Activity就会请求AMS渲染它所管理的视图。此时Activity一定位于栈顶,并处于运行状态。
(4)onPause():当系统准备启动或恢复另一个Activity时被调用,即当前Activity即将从可见状态变为不可见时调用。通常会将一些消耗CPU的资源在这里释放掉,或者在这里保存一些关键数据。
(5)onStop():当系统启动或者恢复另一个Activity,当前Activity被新Activity完全遮挡,变为完全不可见时被调用。
注意:onPause与onStop的区别:onStop必须是当前Activity被新Activity全部遮挡,变得完全不可见的时候才会被调用。如果新Activity只是遮挡了当前Activity的一部分(如新Activity是一个对话框式的Activity),当前Activity仍有部分可见,但是无法对其进行操作,此时只有onPause会被调用,而onStop不会被调用。
(6)onDestory():在Activity将被销毁时调用,之后Activity被销毁,变为销毁状态。
(7)onRestart():当Activity进入onStop状态后,又要重新恢复运行状态时被调用。
上述从(1)~(6)就是一个完整的Activity生命周期。通常会根据情况,选择在合适的周期函数内调用执行需要代码,如在onCreate中进行一些初始化操作,在onDestory的时候释放内存资源等。并非每个时期的Activity都是可见的,只有onResume()和onStop()期间的Activity是可见的,此时用户可与Activity进行交互。
为了帮助开发者更好的理解Activity的生命周期,Android官方提供了一张Activity的生命周期图。通过这张图,可以更好的理解Activity生命周期的执行过程。
图1 Activity生命周期
Android应用程序中,一般情况下,每打开一个界面(或者说每执行一次界面跳转),就会产生一个Activity实例。Android中通过使用栈的方式来管理Activity实例。栈是一种后进先出的集合。一般情况下,当前显示的Activity位于栈顶,当用户进行退出界面的操作时,系统便将当前栈顶的Activity出栈,此时,原来位于栈顶Activity之下的Activity就会变为栈顶Activity,在设备上显示。
然而,实际中可能没有那么简单。我们经常会遇到一些特殊情况需要对Activity实例进行一些特殊处理。例如,为了避免重复创建Activity,要求一个Activity只能有一个实例。这些特殊情况,就要通过设置Activity的启动模式来实现。那么Activity的启动模式是什么?又该如何设置呢?下面就来看一下。
(1)在AndroidManifest.xml中注册Activity并设置启动模式
AndroidManifest.xml可以称为Android项目中的清单文件。在这个文件里面,主要是对整个应用进行一些配置,如应用的package、应用所需的权限、应用的图标、名称等。同时,每当在项目中新添加一个Activity、Service(无论是新建的还是从外部项目copy的),都要在这个清单文件中进行注册,否则程序运行时便会出错。
那么,如何在清单文件中注册Activity呢?来看下面代码:
在AndroidManifest.xml中注册MainActivity,并将MainActivity的launchMode(启动模式)为standard(标准启动模式),同时设置MainActivity为应用的启动界面。
android:name="com.test.myapplication.MainActivity"
android:launchMode="standard">android:name="android.intent.action.MAIN" /> android:name="android.intent.category.LAUNCHER" />
如同上述代码,在清单文件中注册Activity,就是在该文件的
注意观察上述代码,发现代码中还有一个
(2)Activity的四种启动模式
Activity的启动模式分为standard、singleTop、singleTask、singleInstance四种,下面分别来介绍:
● standard(标准启动模式)
standard模式是Activity的默认启动模式。处于该模式下的Activity可以被多次创建。也就是说,任何时候无论Activity栈中是否存在该Activity,且如果存在,则无论该Activity是否位于栈顶,当执行诸如startActivity操作时,系统都会启动一个新的Activity实例,并将其置于栈顶。Activity栈的变化如下图所示:
图2 standard模式的Activity在栈中存在多个实例
● singleTop
以singleTop模式启动的Activity,如果该Activity已有一个实例处于栈中,并且位于栈顶,则再次启动该Activity时不会创建新的实例,而是会重用处于栈顶的那个实例,并在onNewInent()方法中将Intent对象传递到这个实例中。此时,Activity栈的变化如下图:
图3 singelTop模式重用位于栈顶的自身的Activity实例
如果一个Activity以singleTop启动,并且在栈中存在该Activity的一个实例,但是该实例不位于栈顶,那么再次启动该Activity时,将会创建一个新的实例,并将新的实例位于栈顶。此时,Activity栈的变化如下图:
图4 singleTop模式新建Activity实例位于栈顶
● singleTask
singleTask模式下的Activity在Activity栈中只能有一个实例存在。也就是说,当启动一个Activity时,如果栈中没有该Activity实例,将会创建一个新的实例并位于栈顶;
图5 singleTask模式新建Activity实例位于栈顶
如果栈中已经有一个实例,并且该实例没有位于栈顶,那么系统将会销毁处于该Activity之上的所有Activity,使得该Activity实例位于栈顶;
图6 singleTask模式销毁自身上层所有Activity使自身实例位于栈顶
如果该Activity实例已经位于栈顶,则重用该实例。Activity栈的变化如下图:
图7 singleTask重用位于栈顶的自身的Activity
● singleInstance
如果一个Activity设置了singleInstance启动模式,它将在一个独立的任务中开启,且这个独立任务中有且只有这一个实例。当再次启动该Activity时,会重用已存在的任务和实例。
注意,对于singleInstance模式下的Activity,同一时刻在系统中只会存在一个实例。这里要与singleTask做一个比较:对于singleTask模式的Activity,在同一个栈中只会有一个实例,但是对于不同的任务栈,每个栈是可以自己拥有一个实例的。举个例子:应用A和应用B同时启动了一个singleTask模式的ActivityA,此时在系统中,由于应用A和应用B分别有自己的任务栈,因此在应用A和应用B的任务栈中会各有一个ActivityA实例,如下图:
图8 singleTask模式的Activity实例可以同时存在于系统中不同的任务栈中
而对于singleInstance模式的Activity,同一时刻在系统中只会有一个实例存在,并且该实例单独位于一个独立的任务中。无论系统中有多少个应用启动了该Activity,系统中都只会有一个该Activity实例。如下图:
图9 singleInstance模式下Activity在系统中只会有一个实例存在
后记:Activity的生命周期和启动模式可以说是Activity中比较重要的内容,熟记和灵活使用它们,有利于在实际开发中实现对业务流程的控制,实现某些特殊的功能需求。