Android App开发基础篇—四大组件之Activity生命周期和启动模式

    前言:作为一个页面单元,Activity在Android App开发中承担着显示页面,加载UI元素,提供应用与用户交互窗口的重要作用。那么,从创建,显示,直到关闭,Activity经历了怎样的一个过程?系统又是如何对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生命周期

二、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,就是在该文件的 标签对中添加一对   标签,同时指定标签的name属性,name属性的值为该Activity在项目文件中的具体路径。如上面MainActivity位于项目的 com.test.myapplication包中,name的值就为com.test.myapplication.MainActivity一般如果只是简单注册Activity,只需这样就行了。而我们是要设置Activity的启动模式,因此还需设置launchMode属性。launchMode共有4中可选模式,下面再来一一介绍。

    注意观察上述代码,发现代码中还有一个标签对在这里暂时还没什么用处,因此暂时不做具体介绍。大家只需记住:上面代码中的的作用是把该MainActivity指定为应用程序启动的首页,即打开应用后显示的第一个页面。一般情况下,在清单文件中注册Activity是不需要设置的,这里是因为MainActivity作为了程序首页,所以才有了

   (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中比较重要的内容,熟记和灵活使用它们,有利于在实际开发中实现对业务流程的控制,实现某些特殊的功能需求。


更多相关文章

  1. Android(安卓)uiautomator实例使用
  2. android 4.0以上无法收到开机广播
  3. 解读Android之Intents和Intent Filters
  4. Android的IPC机制和多进程开发模式
  5. 进入android项目组的第一天
  6. blcr加速android启动速度遇到的问题及解决方法
  7. Android(安卓)Launcher 分析
  8. Android文件读写实例代码
  9. android中wifi原理及流程分析(很经典)

随机推荐

  1. Android中的color.xml的说明
  2. 如何在ActionBar上面添加popup menu
  3. android调试信息
  4. Android can not create linked resource
  5. android读取Resources中内容
  6. 在Android命令行启动程序的方法
  7. Android 入门文档__ContentProvider详解
  8. android上进行c/C++开发测试
  9. android添加文件打开方式以及参数传递
  10. Android(安卓)解决bug:异常提示"ListView