1、定义
Activity是为用户提供可视化界面并可以与用户交互的组件。
2、概述
应用程序通常是多个松散并相互绑定的Activity组成。一般,用户***启动应用时,将启动一个被指定为main的Activity。每个Activity都可以启动另一个Activity,以执行不同的动作。每次启动一个新的Activity,以前的Activity停止,但在系统堆栈保留Activity(“回栈”)。一个新的Activity启动时,它将当前Activity压到栈里面并取得用户的焦点。回堆栈遵守基本的“后进先出”的堆栈机制。当用户在当前Activity,按下返回按钮,则当前弹出堆栈(并销毁)和恢复以前的Activity。
Activity停止是因为一个新的Activity开始,通过活动的生命周期回调方法,通知这种状态发送变化。一个Activity可能会收到多个回调 方法,当状态发生变化时.产生,停止,恢复,销毁,这些回调在适当的时机提供给您做相应工作的机会。例如,停止时,你的Activity应该释放大型对 象,如网络或数据库连接。恢复Activity时,你可以重新获得必要的资源和恢复被中断的Activity。这些状态转换是所有的Activity程序 周期的一部分。
3、创建Activity
a. 概述
要生成一个Activity,你必须生成一个Activity子类Activity(或已有的子类)。在你的子类中,创建,停止,恢复或销毁 Acitivty时,你需要实现回调方法,系统调用时,用这些方法在Activity生命周期的各种状态之间的转换。两个最重要的回调方法是:
onCreate():必须实现这个方法。生成Activity时系统调用。在你实现中,你应该初始化您的Activity中的组件。最重要的是,这是你必须调用 setContentView() 定义Activity的用户界面的布局。
onPause():当用户离开你的Activity时候(尽管它并不总是意味着被销毁Activity),系统调用此方法。通常如果你需要保持当前会话的话,你所有的改动都应在这提交(因为用户可能不返回)。
还有其他几个生命周期回调方法,你应该使用这些方法处理Activity与导致使Activity必须停止,甚至销毁的突发中断之间的事情,来提供流畅的用户体验。所有的生命周期回调方法将在稍后讨论,在有关 管理Activity生命周期部分。
b. 实现用户界面
一个Activity的用户界面是由一组按层派生视图类-View的视图对象组成。每个视图控制Activity窗口的特定矩形空间,以响应用户交互。例如,一个视图可能是一个按钮,当用户触摸它启动一个操作。
Android提供了一些现成的视图,你可以用它来设计和组织布局。“Widgets”就是视图-view,他提供一个可视的可交互的屏幕元素,如按钮,文本字段,复选框,或只是一个图象。“布局”是从视图组-ViewGroup派生的,提供了对子视图特殊的布局模式,如线性布局,网格布局,或相对布局的视图组。还可以继承视图类-View和视图组 - ViewGroup(或现有的子类)来创建自己的Widgets和布局,并将其应用到您的Activity布局中。
最常见的方式来定义一个布局,是一个XML布局文件保存您的应用程序资源。这种方式,你可以单独从源代码中维护你的用户界面设计以及定义Activity 的行为。你可以通过setContentView()设置您的Activity的UI布局 ,传入布局的资源ID。或者,你也可以在Activity代码中生成新的视图-View,新建立一个视图 - View层次结构插入到视图组-ViewGroup ,然后传入根视图组-ViewGroup给setContentView()进行布局。
c. 在manifest文件中声明Activity
要在系统中使用Activity,您必须在manifest文件中声明您的Activity。打开你的manifest文件,并添加 <activity-element>>作为 <application><application> 元素一个子元素。例如:
- <manifest ... >
- <application ... >
- <activity android:name=".ExampleActivity" />
- ...
- </application ... >
- ...
- </manifest >
在这个元素可以包含其他一些属性,包括定义属性,如Activity的标签,图标的Activity,或Activity的主题UI风格。 属性android:name 是唯一需要的属性,它指定Activity的类名。一旦你发布你的应用程序,你不应该改变这个名字,因为如果这样做,你可能会破坏一些功能,如应用程序的快捷方式。
d. 使用intent过滤器
一个 <activity> 元素也可使用 <intent-filter>的元素指定的各种intent过滤器,以说明其他应用程序组件可以如何激活它。
当你使用Android SDK工具为您创建一个新的应用,<activity>标签下自动包括用于声明Activity响应main的动作的intent过滤器和用于启动的lancher分类。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>
<action> 元素指定应用程序main的入口。 <category> 元素指定系统的activity列表上应用启动的Activity,(允许用户启动这个Activity)。
如果你打算让您的应用程序成为一个独立的应用,不允许其他应用程序启动应用中的Activity,那你就不需要其他的intent过滤器。 如前面示例所示,只有一个Activity带有main动作和launcher类别。你 不让其他Activity用于其他应用程序,那他们不应有任何intent过滤器,你必须显示的调用intent启动他们。
但是,如果您希望您的 Activity响应其他应用程序(和自己)的隐式intent,那么你必须在您的Activity中定义额外的intent过滤器。为了响应你需要响应 的每种intent,你必须包括 <intent-filter> ,其中包括一个 <action> 元素的和一个可选的 <category> 元素和/或 <data> 元素。这些元素指定你的Activity可以响应的intent类型。
4、启动Activity
你就可以通过调用 startActivity(android.content.Intent) startActivity()启动另一个Activity,它传递一个Intent描述你要启动的Activity。intent指定你要启动的 Activity,或描述要执行的动作类型(系统为您选择合适的Activity,甚至可能是他应用程序的Activity)。intent也可携带少量 数据被用于要启动的Activity。
在自己的应用程序中,你会经常需要简单地启动一个已知的Activity。你可以使用类名来创建一个intent,明确定义你要启动的Activity。另 外,您的应用程序可能还需要执行一些动作,例如发送电子邮件,文字信息,或状态更新,使用Activity中的数据。在这种情况下,你的应用程序可能无法 有其自身的Activity,执行这些行动,所以你可以转而利用设备上其他应用程序提供的Activity为您执行。这是intent真正有价值的地方 ——你可以创建一个描述了要执行的一个动作的intent,系统从另一个应用程序启动的适当Activity。
如果有多个Activity可以处理的intent,那么用户可以选择使用哪一个。例如,如果你想允许用户发送电子邮件,你可以创建以下intent:
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
- startActivity(intent);
a. 启动activity的返回结果
有时,您要取得你启动的Activity的结果。使用Activity的startActivityForResult()。然后在后续实现了 onActivityResult()回调方法的Activity中取得结果。后续Activity完成后,它会返回一个intent给您 onActivityResult()方法。
- private void pickContact() {
- / /根据CONTENT PROVIDER URI定义,建议一个用于选择联系人得 INTENT
- Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
- startActivityForResult(intent, PICK_CONTACT_REQUEST);
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- / /如果请求正常(OK)并且请求是PICK_CONTACT_REQUEST
- if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
- / /查询 content provider 取得联系人的名字
- Cursor cursor = getContentResolver().query(data.getData(),
- new String[] {Contacts.DISPLAY_NAME}, null, null, null);
- if (cursor.moveToFirst()) { // 游标不为空
- int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
- String name = cursor.getString(columnIndex);
- // 对选中名字的人进行处理...
- }
- }
- }
5、关闭Actvity
您可以通过调用 finish()方法关闭Activity的。你也可以通过调用 finishActivity()关闭之前您启动的一个独立的Activity 。注意:在大多数情况下,你应该不需要显示地使用这些方法结束Activity。在下面一节讨论有关的Activity生命周期,Android系统为你管理Activity, 所以你不需要来自己结束Activity。调用这些方法可对用户体验产生影响,只有你确定不想让用户返回此Activity实例时使用。
6、管理Activity生命周期
a. 实现生命周期函数
b. 保存activity状态
恢复状态:在管理Activity生命周期中提到当Activity暂停或者停止的时候,会保留Activity状态。因为当他暂停或者停止的时候,内存中 仍然有 Activity 对象,并且包含成员信息和当前的状态,因此,在用户模式下的任何对Activity的操作,在Activity返回到前台的时候将被还原("恢复状态")。
重新运行状态:在Activity变得不太稳定的前,系统调用 onSaveInstanceState() 。该系统传递给其一个 Bundle,您可以在其中以名称-值对的形式保存为有关Activity的状态信息,如使用方法 putString()和 putInt() 。然后,如果系统kill你的应用进程,当用户返回Activity,系统重建Activity时,系统会同时传给 onCreate() 和 onRestoreInstanceState() Bundle 。
使用这两种方法,你可以从 Bundle 提取到保存的状态信息来恢复Activity。如果没有恢复的状态信息, Bundle传递的是空(***创建Activity的情况)。由于onSaveInstanceState() 的默认实施能保存UI的状态,如果要为保存额外的状态信息而重写此方法,那么在做任何工作之前,你一定要在实现 onSaveInstanceState() 之前调用其超类方法。
同样,如果你重写它,你也应该调用 onRestoreInstanceState()实现的超类方法,以此默认实现恢复视图状态。因为 onSaveInstanceState() 不能保证被调用,所以当用户离开Activity,你应该只使用它记录Activity的瞬时状态(UI的状态),你不应该用它来存储持久数据。相 反,你应该使用 onPause() 存储持久数据(如保存到数据库中的数据)。
c. 处理配置改变
某 些设备配置在运行时可以改变(如屏幕方向,键盘的可用性,和语言)。当这种变化发生时,Android重新运行Activity(系统调用的 onDestroy(),然后立即调用的 onCreate())。这种行为旨在帮助您用您所提供的(如不同的屏幕方向和大小不同的布局)的替代资源进行应用程序自动重载,以适应新的配置。如果你 正确地设计Activity,以处理由于屏幕方向的变化带来的重新启动并按照如上所述恢复Activity状态,那么您的应用程序在Activity生命 周期中对于其他突发事件的应对将更具弹性。处理重新启动来保存和恢复Activity状态的一个的***方式是使用onSaveInstanceState()和onRestoreInstanceState()(或onCreate())。
7、协调Activities
在同一进程中两个Activity中,当Activity A 启动Acivity B是产生的操作顺序:
1.Activity A执行onPause()方法;
2.Activity B按照onCreate(),OnStart(),onResume()的顺序执行方法。(ActivityB现在取得用户的焦点。)
3.如果ActivityA已不再是显示在屏幕上,它执行方法onStop()。
这个可预测的生命周期回调顺序,可让您管理的从一个Activity到另一个Activity的转换信息。例如,如果***个Activity停止时你必须写数据库 , 让之后的Activity读取数据库,那么你应该在onPause()期间写数据库而不是onStop()。