Android组件Activity
什么是Activity
首先我们要知道Activity是一个什么东西)。Activity是Android用得最多且是最基本的组件。官方的说法是Activity一个应用程序的组件,它提供一个屏幕来与用户交互,以便做一些诸如打电话、发邮件和看地图之类的事情,原话如下:“An Activity is an application component that provides a screen with which users can interact in order to do something, such as dial the phone, take a photo, send an email, or view a map.”。
Activity的生命周期
借用两张经典Activity生命周期图:
从这两张图上可以看到,Activity 的整个生命周期发生在 onCreate() 调用与 onDestroy() 调用之间。
a).Activity 应在 onCreate() 中执行“全局”状态设置(例如定义布局),并释放 onDestroy() 中的所有其余资源。例如,如果您的 Activity 有一个在后台运行的线程,用于从网络上下载数据,它可能会在onCreate() 中创建该线程,然后在 onDestroy() 中停止该线程。
b).Activity 的可见生命周期发生在 onStart() 调用与 onStop() 调用之间。在这段时间,用户可以在屏幕上看到 Activity 并与其交互。 例如,当一个新 Activity 启动,并且此 Activity 不再可见时,系统会调用 onStop() 。您可以在调用这两个方法之间保留向用户显示 Activity 所需的资源。 例如,您可以在 onStart() 中注册一个 BroadcastReceiver 以监控影响 UI 的变化,并在用户无法再看到您显示的内容时在 onStop() 中将其取消注册。在 Activity 的整个生命周期,当 Activity 在对用户可见和隐藏两种状态中交替变化时,系统可能会多次调用 onStart() 和 onStop()。
c).Activity 的前台生命周期发生在 onResume() 调用与 onPause() 调用之间。在这段时间,Activity 位于屏幕上的所有其他 Activity 之前,并具有用户输入焦点。 Activity 可频繁转入和转出前台 — 例如,当设备转入休眠状态或出现对话框时,系统会调用 onPause() 。 由于此状态可能经常发生转变,因此这两个方法中应采用适度轻量级的代码,以避免因转变速度慢而让用户等待。
在清单文件中声明 Activity
AndroidManifest 文件中声明 Activity,并将元素添加为元素的子项。这样系统才能访问它。例如:
<mainfest ...>
<application ...>
<activity android:name=".MainActivity"/>
....
</application>
</mainfest>
还可以在此元素中加入几个其他特性,以定义 Activity 标签、Activity 图标或风格主题等用于设置 Activity UI 风格的属性。android:name属性是唯一必需的属性—它指定 Activity 的类名。应用一旦发布,即不应更改此类名,否则,可能会破坏诸如应用快捷方式等一些功能。
使用 Intent 过滤器
元素还可指定各种 Intent 过滤器—使用元素—以声明其他应用组件激活它的方法。
使用 Android SDK 工具创建新应用时,系统自动创建的存根 Activity 包含一个 Intent 过滤器,其中声明了该 Activity 响应“主”操作且应置于“launcher”类别内。 Intent 过滤器的内容如下所示:
<activity android:name=".MainActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.Main"/>
<category android:name="android.intent.category.LUNCHER"/>
</intent-filter>
</activity>
<action> 元素制定这是应用的“主”入口点,<category> 元素制定此 Activity 应列入系统的应用启动器内(以便用户启动该 Activity)。
如果打算让应用成为独立应用,不允许其他应用激活其 Activity,则不需要任何其他Intent 过滤器。 正如前例所示,只应有一个 Activity 具有“主”操作和“launcher”类别。 不提供给其他应用的 Activity 任何 Intent 过滤器。
启动Activity
从官方API看:
可以通过调用 startActivity(),并将其传递给描述想启动的 Activity 的 Intent 来启动另一个 Activity。Intent 对象会指定想启动的具体 Activity 或描述想执行的操作类型(系统会为您选择合适的 Activity,甚至是来自其他应用的 Activity)。 Intent 对象还可能携带少量供所启动 Activity 使用的数据。
在您的自有应用内工作时,您经常只需要启动某个已知 Activity。 您可以通过使用类名创建一个显式定义您想启动的 Activity 的 Intent 对象来实现此目的。 例如,可以通过以下代码让一个 Activity 启动另一个名为SignInActivity的 Activity:
Intentintent=newIntent(this,SignInActivity.class);
startActivity(intent);
不过,您的应用可能还需要利用您的 Activity 数据执行某项操作,例如发送电子邮件、短信或状态更新。 在这种情况下,您的应用自身可能不具有执行此类操作所需的 Activity,因此您可以改为利用设备上其他应用提供的 Activity 为您执行这些操作。 这便是 Intent 对象的真正价值所在 — 您可以创建一个 Intent 对象,对您想执行的操作进行描述,系统会从其他应用启动相应的 Activity。 如果有多个 Activity 可以处理 Intent,则用户可以选择要使用哪一个。 例如,如果您想允许用户发送电子邮件,可以创建以下 Intent:
Intentintent=newIntent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL,recipientArray);
startActivity(intent);
添加到 Intent 中的EXTRA_EMAILextra 是一个字符串数组,其中包含应将电子邮件发送到的电子邮件地址。 当电子邮件应用响应此 Intent 时,它会读取 extra 中提供的字符串数组,并将它们放入电子邮件撰写窗体的“收件人”字段。 在这种情况下,电子邮件应用的 Activity 启动,并且当用户完成操作时,您的 Activity 会恢复执行。
还有一种 启动 Activity 以获得结果:
有时可能需要从启动的 Activity 获得结果。在这种情况下,请通过调用startActivityForResult()(而非startActivity())来启动 Activity。 要想在随后收到后续 Activity 的结果,请实现onActivityResult()回调方法。 当后续 Activity 完成时,它会使用Intent向您的onActivityResult()方法返回结果。
例如,您可能希望用户选取其中一位联系人,以便您的 Activity 对该联系人中的信息执行某项操作。 您可以通过以下代码创建此类 Intent 并处理结果:
privatevoidpickContact(){
// Create an intent to "pick" a contact, as defined by the content provider URI
Intentintent=newIntent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
startActivityForResult(intent,PICK_CONTACT_REQUEST);
}
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
// 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
Cursorcursor=getContentResolver().query(data.getData(),
newString[]{Contacts.DISPLAY_NAME},null,null,null);
if(cursor.moveToFirst()){// True if the cursor is not empty
intcolumnIndex=cursor.getColumnIndex(Contacts.DISPLAY_NAME);
Stringname=cursor.getString(columnIndex);
// Do something with the selected contact's name...
}
}
}
上例显示的是,您在处理 Activity 结果时应该在onActivityResult()方法中使用的基本逻辑。 第一个条件检查请求是否成功(如果成功,则resultCode将为RESULT_OK)以及此结果响应的请求是否已知 — 在此情况下,requestCode与随startActivityForResult()发送的第二个参数匹配。 代码通过查询Intent中返回的数据(data参数)从该处开始处理 Activity 结果。