Activity 简介
Activity 是应用程序的四大组件之一,为用户提供一个交互界面,比如打电话、发短信、发送邮件等。每一个Activity都会提供一个窗口用于绘制用户界面。通常窗口都是全屏,但是也可以浮在其他的窗口之上。
app一般由一个或者多个Activity松散耦合在一起。最常见的情况是,一个Activity被指定为“mian”Activity,作为用户启动app时最先进入的界面。Activity可以启动其他的Activity界面来满足不同德操作。每次开启一个新的Activity时会先关闭当前的Activity,然后将其保存在“Back Stack”(类似先进后出的栈结构),默认情况下,被关闭的Activity会被放在Back Stack中,当用户按下返回键时,以前的Activity会从栈顶弹出并获得用户的焦点。(关于Back Stack的部分会在Tasks and Back Stack文档中详细讨论)
当一个Activity因为新开启一个Activity是被关闭,他会将Activity状态的变化通知Activity的“生命周期回调”方法。Activity的生命周期被分为几个状态:creation、started、stopped、pause、resume、destroy,每个状态会对应一个回调方法。系统会在Activity状态发生改变的时候回调这些方法,这样你就有机会指定一些适当的代码。举个例子,当你关闭一个Activity的时候你必须释放一些太好内存的对象,比如网络、数据库连接等。当Activity恢复时,你可以再次申请那些必要的资源来恢复之前被中断的操作。
这篇文章剩余的部分会讨论如何创建和使用一个Activity,包括Activity生命周期的状态切换,以及如何处理状态的变换。
Activity的创建
首先你需要创建一个子类来继承Activity。在子类中需要实现回调方法以提供给系统在不同的状态下调用,其中最重要的两个回调函数如下:
- 这个方法你必须实现。系统在Activity被创建的时候会调用此方法。在此方法中你应用初始化Activity必须用到的资源。最终要的时候你需要调用 setContentView()设置Layout文件来填充你的用户界面。
- 当用户离开当前的界面时会调用此方法,虽然不一定会终止Activity,但是有可能此界面不会在恢复,所以你需要保存一些用户的设置,以保证用户的设置生效。
onCreate()
onPause()
还有一些其他的生命周期回调方法,你应该合理的运用这些回调方法,保证在正不同Activity切换和Activity被异常中断的情况下仍然有一个流畅的用户体验,稍后会在Managing the Activity Lifecycle 一节中详细的讨论所有的回调方法。
实现用户界面
一个用户界面由不同级别的视图(view)组成—view是继承于View类的对象。每一个视图都控制者Activity窗口中的一个矩形区域,而且可以与用户交互。举个例子,一个视图可能是一个按钮,当用户点击时可以触发某个操作。
Android 提供了许多现成的视图(view),你可以用来设计和组织你layout(布局)。“Widgets”是view的别称,它提供了一个在屏幕可视化的元素,比如一个按钮(button)、文本框(Text filed)、单选框(checkbox)、或者仅仅是一副图像(image)。“Layout”继承于ViewGroup,为view提供了一个特有的布局模型,比如线性布局(LinearLayout)、网格布局(grid Layout)、相对布局(relative Layout)。当然,你也可以直接继承 View
和ViewGroup
类来创建自己的widget和layout,然后应用到Activity的布局中。
一般会在app的资源文件中定义一个XML Layout文件。通过这个方法,你可以将Activity的行为与用户的界面分开维护。每一个布局文件都有一个ID,你可以调用setContentView(layout ID)方法为你的Activity设置布局文件,你也可以在代码中(分级式地)创建view并插入到ViewGroup中,然后将ViewGroup作为layout参数传递给setContentView()。
要知道如何创建用户界面可以参照 User Interface 。
在AndroidManifest.xml中声明Activity
为了保证系统能够访问你的Activity,你需要在AndroidManifest.xml文件中进行声明。声明方式如下:打开工程目中的AndroidManifest.xml文件,在<application>元素中添加一个子元素<activity>:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
<activity>元素下还可以增加其他属性,比如增加一个标签、定义Activity的风格或主题。android:name
属性是必须设置的,它指明了Activity的类名。一旦你发布app,你的类名就不能随意的更改,否则会破坏一些功能,比如已经创建好的app快捷方式,如果你更改了android:name
,快捷方式就会失效。(read the blog post, Things That Cannot Change).
参考 <activity>
可以获得更详细的信息。
“intent filter”的使用
AndroidManifest.xml文件中,为了方便其他的app能够激活你的activity,可以在<activity>
增加<intent-filter>
元素。
当你用Android SDK tools创建一个app时,它会自动为你创建一个放在“launcher” 类中的activity的存根,以便响应“main”action,inten 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>
<action>
标识了app的“main”入口,<category>
表示activity会被放在系统的ApplicationLauncher中,以便用户启动(launch)这个activity。
如果你打算只在当前app中使用该activity,而且不允许其他app激活该activity,那你就不需要任何intent filter。如同上面的例子,只能有一个activity的intent filter 能用户“main”action和“launcher”category。你不需要其他app访问的activity则不需要声明intent filter,该activity所在的app只需要指定activity类名就可以启动了。
在<intent-filter>
下也可以增加<category>
和<data>
元素。这些元素可以指定你的activity可以响应的intent类型。想了解更多关于activity响应intent的方式,可以参考Intents and Intent Filters。
启动Activity
你可以调用startActivity((Intent intent, Bundle options))来启动其他的Activity,intent用于描述想要启动的Activity。intent可以是明确指定启动的Activity类名,或者描述你要启动的动作(系统会根据你的描述为你选择一个合适的Activity,甚至从不同app查找也是有可能的)。intent也可以携带少量的数据传递给需要启动的Activity。
在Activity内部启动当前app中的其他Activity可以直接在intent中指定类名,方式如下:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
然而,你的app执行的某些操作,比如打电话、发短信、查看地图,但是你的app可能没有完成这些功能的Activity,这个时候你可以利用设备上其他具备这些功能的Activity来完成这些操作。intent真正的价值在于,你只需要描述你想要做的操作,系统会自动为你匹配合适的Activity,如果存在相同功能的Activity的时候,会再提示用户选择。举个例子,如果你允许用户发邮件,你可以像下面这样创建一个intent:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
putExtra中recipientArray是一个email 地址的字符串,当带有email功能的app响应这个intent的时候,它会解析recipientArray中的内容然后放到收件人的地址栏里。这种情况下,email 发送后会再恢复你之前的Activity。
Activity 的反馈机制
有时候,你可能希望启动的Activity完成操作后能回传数据。这种情况下,你可以调用startActivityForResult()来启动Activity(而不是调用startActivity())。为了能接收Activity处理的结果,你需要实现回调方法:onActivityResult()。当被启动的Activity推出后会返回一个intent给onActivityResult()。
举个例子,可能你想要用户选择一个联系人,然后你的Activity就可以使用联系人信息做一些事情。上代码:
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);
}
@Override
protected 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()用法。返回的数据通过ContentResolver
查询到contact的Cursor。更详细的信息可以参考Content Providers 。
转载请注明出处:http://blog.youkuaiyun.com/jack_chen_00/article/details/9771569