Android移动应用开发技术与实践
上QQ阅读APP看书,第一时间看更新

2.1 Activity

2.1.1 Activity简介

Activity是Android组件中最基本也是最为常见的四大组件之一。Android四大组件有活动(Activity)、服务(Service)、内容提供者(Content Provider)、广播接收器(BroadcastReceiver)。

Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互,以完成某项任务。Activity中所有操作都与用户密切相关,是一个完全与用户交互的组件,可以通过setContentView(View)来显示指定控件。在一个Android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件,也可以监听并处理用户的事件,做出响应。Activity之间通过Intent进行通信。Intent将在2.2节中进行介绍。

2.1.2 活动状态与活动的生命周期

1.活动状态

活动(Activity)是由活动栈进行管理,当来到一个新的活动时,此活动将被加入到活动栈顶,之前的活动位于此活动的底部。在活动的生命周期中,有四个重要状态:运行状态、暂停状态、停止状态和销毁状态。

(1)运行状态

表示当前的活动。当一个活动位于返回栈的栈顶时,此时活动就处于运行状态。系统不会回收处于运行状态的活动。

(2)暂停状态

表示失去焦点的活动,仍然可见,但是不能被系统杀死。也就是当一个活动不再处于栈顶位置,但仍然可见时,这个活动就进入了暂停状态。因为并不是每个活动都会占满整个屏幕的,比如对话框形式的活动只会占用屏幕中间的部分区域。处于暂停状态的活动仍然是完全存活着的,系统一般不会回收这种活动,只有在内存极低的情况下,系统才会主动考虑回收这种活动。

(3)停止状态

表示该活动被其他活动所覆盖。当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。系统仍然会为这种活动保存相应的状态和成员变量,但这并不是完全可靠的,当其他地方需要内存时,处于停止状态的活动有可能会被系统回收。

(4)销毁状态

表示该活动结束。即是当一个活动从返回栈中移除后就变成了销毁状态。系统就会回收这种状态的活动,从而保证内存充足。

2.活动的生命周期

掌握活动的生命周期对任何Android开发者来说都非常重要,当你深入理解活动的生命周期之后,就可以写出更加连贯流畅的程序,并在如何合理管理应用资源方面发挥得游刃有余,你的应用程序将会拥有更好的用户体验。

Activity类中定义了七个回调方法,覆盖了活动生命周期的每一个环节,如图2-1所示。

图2-1 Activity的生命周期

1)onCreate():这个方法在活动第一次被创建的时候调用,在此方法中完成活动的初始化操作,比如加载布局、绑定事件等。

2)onStart():此方法被回调时表示活动正在启动,此时活动已处于可见状态,只是还没有在前台显示,因此无法与用户进行交互。可以简单理解为活动已显示而无法看见。

3)onResume():当此方法回调时,则说明活动已在前台可见,可与用户交互了(处于“活动运行中”状态),onResume方法与onStart的相同点是两者都表示活动可见,只不过onStart回调时活动还是在后台,无法与用户交互,而onResume则已显示在前台,可与用户交互。当然从流程图也可以看出当活动停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此也可以在onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。

4)onPause ():此方法被回调时则表示活动正在停止(Paused形态),一般情况下onStop方法会紧接着被回调。但通过流程图还可以看到一种情况是onPause方法执行后直接执行了onResume方法,这属于比较极端的现象了,这可能是用户操作使当前活动退居后台后又迅速地回到到当前的活动,此时onResume方法就会被回调。当然,在onPause方法中可以做一些数据存储、动画停止或者资源回收的操作,但是不能太耗时,因为这可能会影响到新的活动的显示——onPause方法执行完成后,新活动的onResume方法才会被执行。

5)onStop():一般在onPause方法执行完成直接执行,表示活动即将停止或者完全被覆盖(Stopped形态),此时活动不可见,仅在后台运行。同样地,在onStop方法可以做一些资源释放的操作(不能太耗时)。

6)onRestart():这个方法表示活动正在重新启动,当活动由不可见变为可见状态时,该方法被回调。这种情况一般是用户打开了一个新的活动时,当前的活动就会被暂停(onPause和onStop被执行了),接着又回到当前活动页面时,onRestart方法就会被回调。

7)onDestroy():这个方法回调后,活动正在被销毁,也是生命周期最后一个执行的方法,一般可以在此方法中做一些回收工作和最终的资源释放。

以上七个方法中除了onRestart()方法,其他都是两两相对的,因此又可以将活动分为三种生命周期。

1)完整生命周期:活动在onCreate()方法和onDestroy()方法之间所经历的,就是完整生命周期。一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。

2)可见生命周期:活动在onStart()方法和onStop()方法之间所经历的,就是可见生命周期。在可见生命周期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载,在onStop()方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。

3)前台生命周期:活动在onResume()方法和onPause()方法之间所经历的就是前台生命周期。在前台生命周期内,活动总是处于运行状态,此时的活动是可以和用户进行交互的,平时看到和接触最多的就是前台生命周期下的活动。

2.1.3 Activity界面表现

程序中Activity通常的表现形式是一个单独的界面(Screen)。每个Activity都是一个单独的类,它扩展实现了Activity基础类。这个类显示为一个由Views组成的用户界面,并响应事件。

大多数程序有多个Activity。例如,一个文本信息程序有这么几个界面:显示联系人列表界面、写信息界面、查看信息界面和设置界面等。每个界面都是一个Activity。一个界面切换到另一个界面就是载入一个新的Activity。某些情况下,一个Activity可能会给前一个Activity返回值。例如,一个让用户选择相片的Activity会把选择到的相片返回给其调用者。

Android程序员可以决定一个活动的“生”,但不能决定它的“死”,也就是说程序员可以启动一个活动,但是却不能手动地“结束”一个活动。当你调用Activity.finish()方法时,结果和用户按下返回键一样:告诉Activity Manager该活动实例完成了相应的工作,可以被“回收”。随后Activity Manager激活处于栈第二层的活动并重新入栈,同时原活动被压入到栈的第二层,从Active状态转到Paused状态。例如,从Activity1中启动了Activity2,则当前处于栈顶端的是Activity2,第二层是Activity1,当调用Activity2.finish()方法时,Activity Manager重新激活Activity1并入栈,Activity2从Active状态转到Stoped状态,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2返回的数据通过data参数返回给Activity1。

2.1.4 Activity示例

1.建立Activity

与开发Web应用时建立Servlet类相似,建立自己的Activity也需要继承Activity基类。

当一个Activity类定义出来之后,这个Activity类何时被实例化、它所包含的方法何时被调用,这些都不是由开发者决定的,都应该由Android系统来决定。

为了让Servlet能响应用户请求,开发者需要重写Httpservlet的doRequest()和doResponse()方法。Activity与此类似,创建一个Activity也需要实现一个或多个方法,其中最常见的就是实现onCreate()方法,该方法将会在Activity启动时被回调。

在Android中创建一个Activity是很简单的事情,编写一个继承自android.app.Activity的Java类即可。

【例2-1】 建立Activity

运行结果如图2-2所示。

图2-2 项目页面

2.配置Activity

创建完Activity子类之后,此时Activity还不能使用,必须在AndroidManifest.xml文件中配置Activity才行。

Android应用要求所有应用程序组件(Activity)都必须显式进行配置。

只要在<application . . />元素中添加<activity . .>子元素即可配置Activity。

1)name:指定该Activity的实现类。

2)icon:指定该Activity对应的图标。

3)1abel:指定该Activity的标签。

【例2-2】 配置Activity

上面活动的配置文件的节点含义说明如下。

● intent-filter属性:android:priority(例如:有序广播主要是按照声明的优先级别,如A的级别高于B,那么广播先传给A,再传给B。优先级别是用设置priority属性来确定,范围是-1000~1000,数越大优先级别越高)。Intent filter内会设定的资料包括action、data与category三种。也就是说filter只会与intent里的这三种资料作对比动作。

● action属性:action很简单,只有android:name这个属性。常见的android:name值为android.intent.action.MAIN,表明此活动是作为应用程序的入口。

● category属性:category也只有android:name属性。常见的android:name值为android.intent.category.LAUNCHER(决定应用程序是否显示在程序列表里)。

3.启动、关闭Activity

Android应用通常都会包含多个Activity,但只有一个Activity会作为程序的入口,该Android应用运行时将会自动启动并执行该Activity。至于应用中的其他Activity,通常都由入口Activity启动,或由入口Activity启动的Activity启动。

活动(Activity)启动其他Activity有如下两个方法:

startActivity(Intent intent):启动一个活动页面。

startActivityForResult(Intent intent,int requestCode):以指定请求码(requestCode)启动活动,而且程序将会等到新启动活动的结果。

结束活动有下面4种方法,如下所示:

【例2-3】 启动Activity

运行结果如图2-3所示。

图2-3 活动跳转页面

【例2-4】 关闭Activity