一、Activity的基本概念
Activity是Android的四大组件之一,它是一种可以包含用户界面的组件,主要用于和用户进行交互,比如打电话,照相,发送邮件,或者显示一个地图!Activity用于显示用户界面,用户通过Activity交互完成相关操作 , 一个App允许有多个Activity。
二、Activity的生命周期
Activity生命周期是每一个Android开发者都必须掌握的,当我们深入理解活动的生命周期之后,就可以把握应用在运行中各个周期节点的状态,合理安排业务的执行使程序能够流畅的运行。
2.1、Activity的生命周期图
先上一张从图吧,图片看上去一目了然。图片来源(http://www.runoob.com/w3cnote/android-tutorial-activity.html)
2.2、Activity的四种状态
每个Activity在其生命周期中最多可能会有四种状态。
1.运行状态
当一个Activity位于返回栈(关于返回栈的概念下面再介绍)的栈顶时,这时Activity就处于运行状态,系统会将处于栈顶的Activity显示给用户。
2.暂停状态
当一个Activity不再处于栈顶位置,但仍然可见,这时Activity就进入了暂停状态。初学者可能会有这样的疑问,既然Activity都已经不在栈顶了,怎么会还可见呢,这是因为并不是每一个Activity都会占满整个屏幕的,比如对话框形式的Activity只会占用屏幕中间的部分区域。
3.停止状态
当一个Activity不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。
4.销毁状态
当一个Activity从返回栈中移除后就变成了销毁状态。
2.3、Android返回栈
Android是使用任务(Task)来管理Activity的,一个任务就是一组存放在栈里的Activity集合,这个栈被称作返回栈,栈(堆栈)是一种先进后出的数据结构,这里顺便提一下另一种常见的数据结构:队列,队列是一种先进先出的数据结构。
每当启动一个新的Activity时,它会被放入返回栈中,并处于栈顶的位置。每当我们按下Back键或调用activity的finish()方法去销毁一个活动时,处于栈顶的Activity会出栈,这时前一个入栈的Activity就会重新处于栈顶的位置。系统总是会显示处于栈顶的Activity给用户。
2.4、Activity的生存期
Activity类中定义了7个回调方法,覆盖了Activity生命周期的每一个环节,下面来一一介绍这7个方法
1.onCreate()
这个方法在每一个Activity类都会有,当我们新建一个Activity类时,一定会重写父类的onCreate方法,onCreate方法会在Activity第一次被创建时调用。我们应该在这个方法中完成Activity的初始化操作,比如说加载布局,初始化布局控件,绑定按钮事件等。
2.onStart()
这个方法在Activity由不可见变为可见时调用。
3.onResume()
这个方法在Activity准备好和用户交互的时候调用。此时的Activity一定位于返回栈的栈顶,并且处于运行状态。
4.onPause()
这个方法在系统准备去启动或者恢复另一个Activity的时候调用。
5.onStop()
这个方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的activity,那么,onPause()方法会得到执行,而onStop()方法并不会执行。
6.onDestory()
这个方法在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。
7.onRestart()
这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。
三、Activity的创建
要创建 Activity,您必须创建 Activity
的子类(或使用其现有子类)。您需要在子类中实现 Activity 在其生命周期的各种状态之间转变时(例如创建 Activity、停止 Activity、恢复 Activity 或销毁 Activity 时)系统调用的回调方法。 两个最重要的回调方法是:
您必须实现此方法。系统会在创建您的 Activity 时调用此方法。您应该在实现内初始化 Activity 的必需组件。 最重要的是,您必须在此方法内调用setContentView()
,以定义 Activity 用户界面的布局。
系统将此方法作为用户离开 Activity 的第一个信号(但并不总是意味着 Activity 会被销毁)进行调用。 您通常应该在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。
您还应使用几种其他生命周期回调方法,以便提供流畅的 Activity 间用户体验,以及处理导致您的 Activity 停止甚至被销毁的意外中断。 后文的管理 Activity 生命周期部分对所有生命周期回调方法进行了阐述。
3.1、实现用户界面
Activity 的用户界面是由层级式视图 — 衍生自 View
类的对象 — 提供的。每个视图都控制 Activity 窗口内的特定矩形空间,可对用户交互作出响应。 例如,视图可以是在用户触摸时启动某项操作的按钮。
您可以利用 Android 提供的许多现成视图设计和组织您的布局。“小部件”是提供按钮、文本字段、复选框或仅仅是一幅图像等屏幕视觉(交互式)元素的视图。 “布局”是衍生自 ViewGroup
的视图,为其子视图提供唯一布局模型,例如线性布局、网格布局或相对布局。 您还可以为 View
类和 ViewGroup
类创建子类(或使用其现有子类)来自行创建小部件和布局,然后将它们应用于您的 Activity 布局。
利用视图定义布局的最常见方法是借助保存在您的应用资源内的 XML 布局文件。这样一来,您就可以将用户界面的设计与定义 Activity 行为的源代码分开维护。 您可以通过 setContentView()
将布局设置为 Activity 的 UI,从而传递布局的资源 ID。不过,您也可以在 Activity 代码中创建新 View
,并通过将新 View
插入 ViewGroup
来创建视图层次,然后通过将根 ViewGroup
传递到 setContentView()
来使用该布局。
如需了解有关创建用户界面的信息,请参阅用户界面文档。
3.2、在清单文件中声明 Activity
您必须在清单文件中声明您的 Activity,这样系统才能访问它。 要声明您的 Activity,请打开您的清单文件,并将 <activity>
元素添加为 <application>
元素的子项。例如:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
请参阅 <activity>
元素参考文档,了解有关在清单文件中声明 Activity 的详细信息。您还可以在此元素中加入几个其他特性,以定义 Activity 标签、Activity 图标或风格主题等用于设置 Activity UI 风格的属性。 android:name
属性是唯一必需的属性—它指定 Activity 的类名。应用一旦发布,即不应更改此类名,否则,可能会破坏诸如应用快捷方式等一些功能(请阅读博客文章 Things That Cannot Change [不能更改的内容])。
使用 Intent 过滤器
<activity>
元素还可指定各种 Intent 过滤器—使用 <intent-filter>
元素—以声明其他应用组件激活它的方法。
当您使用 Android SDK 工具创建新应用时,系统自动为您创建的存根 Activity 包含一个 Intent 过滤器,其中声明了该 Activity 响应“主”操作且应置于“launcher”类别内。 Intent 过滤器的内容如下所示:
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
如果您打算让应用成为独立应用,不允许其他应用激活其 Activity,则您不需要任何其他 Intent 过滤器。 正如前例所示,只应有一个 Activity 具有“主”操作和“launcher”类别。 您不想提供给其他应用的 Activity 不应有任何 Intent 过滤器,您可以利用显式 Intent 自行启动它们(下文对此做了阐述)。<action>
元素指定这是应用的“主”入口点。<category>
元素指定此 Activity 应列入系统的应用启动器内(以便用户启动该 Activity)。
不过,如果您想让 Activity 对衍生自其他应用(以及您的自有应用)的隐式 Intent 作出响应,则必须为 Activity 定义其他 Intent 过滤器。 对于您想要作出响应的每一个 Intent 类型,您都必须加入相应的 <intent-filter>
,其中包括一个 <action>
元素,还可选择性地包括一个 <category>
元素和/或一个<data>
元素。这些元素指定您的 Activity 可以响应的 Intent 类型。
如需了解有关您的 Activity 如何响应 Intent 的详细信息,请参阅 Intent 和 Intent 过滤器文档。
四、Activity的启动
Activity的启动模式有4种,分别是standard、singleTop、SingleTask、singleInstance,可以在AndroidMainifest.xml文件中指定每一个Activity的启动模式。一个Android应用一般都会有多个Activity,系统会通过任务栈来管理这些Activity,栈是一种后进先出的集合,当前的Activity就在栈顶,按返回键,栈顶Activity就会退出。Activity启动模式不同,系统通过任务栈管理Activity的方式也会不同,以下将分别介绍。
4.1、启动模式
1 Standard模式
Standard模式是Android的默认启动模式,你不在配置文件中做任何设置,那么这个Activity就是standard模式,这种模式下,Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例
2 SingleTop模式
SingleTop模式和standard模式非常相似,主要区别就是当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例,现在把配置文件中FirstActivity的启动模式改为SingleTop,我们的应用只有一个Activity,自然处于任务栈的栈顶。
3 SingleTask模式
SingleTask模式的Activity在同一个Task内只有一个实例,如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈。
4 SingleInstance模式
SingleInstance模式也是单例的,但和SingleTask不同,SingleTask只是任务栈内单例,系统里是可以有多个SingleTask Activity实例的,而SingleInstance Activity在整个系统里只有一个实例,启动一SingleInstanceActivity时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity。
SingleInstance模式并不常用,如果我们把一个Activity设置为SingleInstance模式,你会发现它启动时会慢一些,切换效果不好,影响用户体验。它往往用于多个应用之间,例如一个电视launcher里的Activity,通过遥控器某个键在任何情况可以启动,这个Activity就可以设置为singleInstance模式,当在某应用中按键启动这个Activity,处理完后按返回键,就会回到之前启动它的应用,不影响用户体验。