【Android API指南】App组件(2) - Activities
Activity提供一个用户可交互的界面,比如一个拨号界面,拍照界面,发送邮件的界面。每个activity都被提供一个窗口来绘制界面。窗口一般都是填满屏幕,也可以小于屏幕或者浮动在其他窗口上。
一个程序通常包含多个activity,它们彼此被比较松散的绑定在一起。有一个activity会被指定为“main”activity,在启动程序时被第一个运行。每个activity都可以启动其他的activity来执行不同的动作。新的activity启动,先前的activity就被停止,但是系统会保存先前的activity到堆栈中。当一个新的activity启动时,这个activity被推入后退堆栈中,用户获得它的焦点。后退堆栈遵循“后进,先出”的原则,所以用户完成当前activity然后按Back键时,当前activity就被推出堆栈,先前的activity被恢复。
当一个activity由于新的activity启动而被停止时,通过activity生命周期回调函数来通知状态的改变。当系统创建,停止,恢复,消耗activity时,都会用相应的回调函数执行必要的工作。例如,当activity停止时,你应该释放一些类似网络连接或者数据库连接这样的对象。当activity恢复时,你需要重新获取必要的资源。
下面的内容讨论怎么创建和使用activity,包括activity的生命周期是怎么工作的。
创建Activity创建一个activity你需要先继承activity类,然后实现两个重要的回调函数:
onCreate()
这个方法是必须实现的,用来初始化activity的基本组件,比较重要的是调用setContentView()定义activity的界面布局。onPause()
用户离开activity前第一调用的就是这个方法,这个方法中你应该保存任何需要永久保存的数据,因为用户可能不会再回到这个activity。除了这两个回调函数,还有其他一些生命周期回调函数,下面会介绍。
<manifest ... > <application ... > <activity android:name=".ExampleActivity" /> ... </application ... > ...</manifest >android:name是唯一一个必须的属性,定义了activity的类名,一旦程序发布,这个类名就不能被改变,因为一旦改变就会破坏一些功能,比如程序的快捷方式。
<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>指定为main的<action>元素被指定为应用程序的入口。<category>元素指定了这个activity会被列入系统的程序启动栏中。
Intent intent = new Intent(this, SignInActivity.class);startActivity(intent);不过,你的程序也可以执行一些动作,比如,发送邮件,发送短信,或者更新状态等,这种情况下,你的程序可能没有实现这些功能,所以你可以使用设备上的其他程序来实现。你可以创建一个intent描述一个动作,系统就会运行相应的activity。如果有多个activity符合描述的动作,就会让用户选择一个合适activity来使用,例如,要发送一个邮件的话,可以创建下面的intent:
Intent intent = new Intent(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);startActivity(intent);EXTRA_EMALL附加了邮件地址数组,指定了邮件的收件人。当邮件程序接受了这个intent,就对读取这个邮件地址数组,然后填写到收件人文本框中,当邮件发送完成,你的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);}@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就是用来区别的。activity处于屏幕前台,有用户焦点。Paused
Activity处于部分可见或者不充满整个屏幕。一个Paused状态的activity是完全存活的,不过可能会在系统急需内存的时候被关闭。Stopped
完全被其他activity覆盖,一个stopped状态的activity也是存活在系统后台的,在长时间不使用或者系统急需内存时被关闭。如果activity处于paused或者stopped状态下,系统可以把它从内存中丢弃,不管是调用finish()还是简单的杀死进程。重新打开的话就需要被重新完全创建。
public class ExampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // The activity is being created. } @Override protected void onStart() { super.onStart(); // The activity is about to become visible. } @Override protected void onResume() { super.onResume(); // The activity has become visible (it is now "resumed"). } @Override protected void onPause() { super.onPause(); // Another activity is taking focus (this activity is about to be "paused"). } @Override protected void onStop() { super.onStop(); // The activity is no longer visible (it is now "stopped") } @Override protected void onDestroy() { super.onDestroy(); // The activity is about to be destroyed. }}提示:在做其他工作前通常要先调用超类的实现。
下面的表格介绍了每个回调函数:onCreate()第一次创建时调用,做一些普通静态设置 - 创建视图,绑定数据到list等。NoonStart() onRestart()如果activity已经被停止,调用它重启。NoonStart()onStart()调用它让activity变得可见。NoonResume() onStop() onResume()调用它后activity处于堆栈的顶端,用户可以开始和activity进行交互。NoonPause()onPause()系统启动其他activity时会调用它,这个方法通常用来保存永久的数据,停止动画,或者停止其他消耗cpu的工作。这个方法必须快速执行完毕,因为它执行完才会启动另外一个activity,如果它执行太久,就印象了用户体验。YesonResume() onStop()onStop()当activity不再被用户可见时会调用。原因是这个activity可能要被销毁,或者其他activity已经启动并完全覆盖了这个activity。YesonRestart()onDestroy()onDestroy()activity被销毁时调用。调用它要么是因为activity已经执行完成,要么是系统为了节约空间了暂时销毁它。Yesnothing上表中的“Killable after”的意思是系统是否能够在这个函数执行后直接杀死这个activity,而不执行下面的回调函数。有三个函数是yes,onPause()是第一个,因为在activity创建到被杀掉,onPause()是进程被杀死前能够被保证执行到的最后一个函数。而onStop()和onDestroy()可能会执行不到。所以你应该再onPause()方法中执行写入永久数据的操作。
提示:不能保证onSaveIntanceState()函数在activity销毁前总会被调用到,在一些不需要保存数据的情况下就不会执行,比如用户按back键离开你的activity,这种情况下表明用户明确自己要离开这个activity了,所以就不会调用这个函数保存数据,这个方法在onStop()之前调用,也可能在onPause()之前调用。