Activities

来源:互联网 发布:深圳兰亭科技网络客服 编辑:程序博客网 时间:2024/05/18 00:11

简介

Activity 是这样一个程序组件,它为用户提供一个用于任务交互的画面。例如,拨打电话,拍照,发邮件。或者查看地图。每一个activity都被分配一个窗口。在这个窗口里,你可以绘制用户交互的内容。 这个窗口通常占满屏幕,但也有可能比屏幕小,并且浮在其它窗口的上面。

一个应用程序通常由多个activity组成,它们彼此保持弱的绑定状态。典型的,当一个activity在一个应用程序内被指定为主activity, 那么当程序第一次启动时,它将第一个展现在用户面前。为了展现不同的内容,每一个activity可以启动另外一个。 每当一个新的activity被启动,那么之前的将被停止。但系统将会把它压入一个栈(“back stack”即后退栈),当一个新的activity启动,它将被 放到栈顶并获得用户焦点。后台栈遵循后进先出的栈机制。所以当用户完成当前页面并按下返回按钮时,它将被pop出栈(并销毁),之前的activity将被恢复。 (关于后退栈的更多讨论在任务和后退栈)

当一个activity因为另一个activity的启动而被停止,那么其生命周期中的回调方法,将会以状态改变的形式被调用。 activity通过它自身状态的改变可以收到多个回调方法。当系统创建,停止,恢复,销毁它的时候。并且每个回调方法都给你做相应处理工作的机会。 例如,当停止的时候,你的activity应当释放比较大的对象,例如网络连接,数据连接。当你的activity恢复时,你可以请求必须的资源并恢复一些被打断的动作。 这些状态事务的处理就构成了activity的生命周期。

接下来将讨论如何搭建和使用activity,完整讨论activity的生命周期是怎么工作的,这样你就可以合理地管理不同activity状态间的事务处理。

创建一个Activity

要创建一个activity,你必须创建一个Activity(或者它存在的子类)的子类。 在你的子类里,你需要实现系统调用的回调方法,这些方法用于activity在生命周期中进行事务处理。例如创建,停止,恢复,销毁。其中两个最重要的回调方法分别为:

onCreate()
你必须实现这个方法。系统会在创建activity的时候调用这个方法。 在实现这个方法的同时,你需要实现你activity的重要组件。 最重要的是,你必须在这里调用 setContentView() 来定义你activity用于用户交互的布局。
onPause()
系统将会调用这个方法作为用户离开activity的首先提示(虽然这并不意味着activity正在被销毁)。这通常是你应该在用户会话之前提交并保存任何更改的时机。 (因为用户可能不会再回到这个activity).
你还应该会用到一些其他的生命周期回调方法,它们将帮助你在activity和可能导致你的activity停止甚至销毁之间保持流畅的用户体验。

实现一个用户交互界面

activity的用户接口由一些View的派生类组成的层级结构提供。 每一个view控制acitivity所在window的一个特殊的矩形空间。并且可以响应用户的交互。 例如,一个view可能是一个按钮,当用户碰触的时候将发起动作。

“Layouts”是一组继承了ViewGroup的布局。它们为子视图提供了唯一的布局模型。 例如线性布局,表格布局,相对布局。你也可以继承View和ViewGroup(或它们的子类)去创建你自己的组件或布局,并用它们组成activity布局。

定义布局最常用的方式是使用XML布局文件,它保存在你程序的资源中。这种方式可以保证你的业务逻辑代码和用户交互界面分开。你可以通过setContentView()传递布局文件的ID来设置程序UI。 当然,你也可以在activity代码里自己新建View,并通过插入子View到ViewGroup。 然后把这些视图的根视图传入到setContentView()。

在配置文件中声明activity

为了可以访问activity,你必须把它配置到配置文件中。 首先打开配置文件,在中增加一个元素。例如:

<manifest ... >  <application ... >      <activity android:name=".ExampleActivity" />      ...  </application ... >  ...</manifest >

你可以给这个元素加入很多其他的属性。 例如名称,图标,或者activity的主题风格。 android:name 属性是唯一用来指定acitivity名称的属性。 一旦你发布了程序,就不能改变它的名字,否则将破坏一些功能,例如程序图标。

使用filter

也可以用很多 来指定其他的组件怎样激活它。

当你使用Android SDK tools来创建一个程序,主activity将会自动包含一个被分类为”launcher”的intent filter,如下:

<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 filter,只有一个activity 应该有”main”action和”launcher”分类,例如上述例子。你不想公开的activity应该不包含任何intent filter.但你可以使用明确 的intent来启动它们。(下文将详述)。

然而,如果你想要你的activity响应其他程序(或当前程序)的隐式intent,你必须为activity定义额外的intent filter。 每一个你想响应的intent,都必须包含一个 ,并包含一个 元素,另外,可以包含一个 也可以包含一个 元素。 这些元素指定了intent 的类型。

启动一个Activity

你可以启动一个其他的activity通过调用startActivity(), 并传递一个 Intent , 它用于描述acitity。 intent指定了你想要启动的activity,或者指定了你想展现的动作(系统帮你选择合适的activity,它可能来自于其他的程序)。 intent也可以携带比较小量的数据,用于启动acitivity。

在你自己的应用中,你经常会简单地启动一个已知的activity, 通过创建一个明确的intent。这个intent指定了activity的类名。 例如下面演示了如何启动一个叫SignInActivity的activity:

Intent intent = new Intent(this, SignInActivity.class);startActivity(intent);

然而,你的程序可能想要展示某些动作,例如发邮件,短信,微博,或者使用你activity中的数据。 这时候,你就不应该使用自己的activity来做这些工作。你应该调用系统中其他程序提供的响应功能。 这是intent真正体现其价值的地方。你可以创建一个描述了响应动作的intent,然后系统来为你挑选完成任务的程序。 如果有多个选择,系统会提示用户进行选择。例如你想让用户发邮件,你可以创建下面的intent:

Intent intent = new Intent(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);startActivity(intent);

EXTRA_EMAIL 是一个邮件intent中添加的额外字符串数组,它指定了邮件该发给哪些邮件地址。当一个邮件程序响应了这个intent, 它将读取这些地址,并把他们放置到邮件表单的被发送人栏。这时,邮件程序被启动。当用户完成了发送操作,你的activity会被恢复。

启动一个带返回结果的activity

有时候,你想要启动一个activity,并从这个activty获得一个结果。 这时,要通过 startActivityForResult() (取代startActivity()) 来启动activity。 然后通过实现onActivityResult()回调方法来获得返回后的结果。 当这个后续的activity被关闭,它将发送一个 Intent 给 onActivityResult() 方法。

例如,你可能想要取一个联系人的信息。下面介绍怎么创建intent并处理结果:

private void pickContact() {    // Create an intent to "pick" a contact, as defined by the content provider URI    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);    startActivityForResult(intent, PICK_CONTACT_REQUEST);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {        // Perform a query to the contact's content provider for the contact's name        Cursor cursor = getContentResolver().query(data.getData(),        new String[] {Contacts.DISPLAY_NAME}, null, null, null);        if (cursor.moveToFirst()) { // True if the cursor is not empty            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);            String name = cursor.getString(columnIndex);            // Do something with the selected contact's name...        }    }}

这个例子展示了使用onActivityResult() 来获取结果的基本方法。 第一步要判断请求是否被成功响应,通过判断resultCode 是不是RESULT_OK—, 然后判断这个响应是不是针对相应的请求— ,此时只要判断requestCode 和发送时提供的第二个参数 startActivityForResult() 是否相匹配。 最后,查询 Intent中的data信息。 (data 参数)。

这个过程中,ContentResolver 开启了一个查询而不是content provider, 它返回一个 Cursor ,这将允许数据被读取。

关闭Activity

你可以通过调用finish() 来终止activity。 你也可以调用finishActivity() 来终止你之前启动了的一个独立activity。

注意: 多数情况下,你不应该明确地通过这些方式来关闭acitivity。 就像下面要讨论的activity的生命周期。系统会为你管理。所以你不必关闭他们。 调用这些方法将有悖于用户体验。它们仅用于你绝对不想让用户再返回这个activity的实例。

0 0
原创粉丝点击