Activity

Activities

活动

Quickview

  • An activity provides a user interface for a single screen in your application
  • Activities can move into the background and then be resumed with their state restored

In this document

  1. Creating an Activity
    1. Implementing a user interface
    2. Declaring the activity in the manifest
  2. Starting an Activity
    1. Starting an Activity for a Result
  3. Managing the Activity Lifecycle
    1. Implementing the lifecycle callbacks
    2. Saving activity state
    3. Handling configuration changes
    4. Coordinating activities

Key classes

  1. Activity

See also

  1. Hello World Tutorial
  2. Tasks and Back Stack

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. Each activity is given a window in which to draw its user interface. The window typically fills the screen, but may be smaller than the screen and float on top of other windows.

一个activity(活动)是应用程序的一个组件,它提供一个用户为了完成某件事(比如打电话、拍照、发送Email或者查看地图)而与之交互的窗口。在每个活动的窗口里我们可以绘制此活动的用户界面。典型的窗口样式充满整个屏幕,但是也可能比屏幕小,而且浮于其他窗口的上方。

An application usually consists of multiple activities that are loosely bound to each other. Typically, one activity in an application is specified as the "main" activity, which is presented to the user when launching the application for the first time. Each activity can then start another activity in order to perform different actions. Each time a new activity starts, the previous activity is stopped, but the system preserves the activity in a stack (the "back stack"). When a new activity starts, it is pushed onto the back stack and takes user focus. The back stack abides to the basic "last in, first out" queue mechanism, so, when the user is的Tasks  done with the current activity and presses the BACK key, it is popped from the stack (and destroyed) and the previous activity resumes. (The back stack is discussed more in the Tasks and Back Stack document.)

一个应用程序通常由多个activity组成,它们相互之间松散的耦合在一起。典型地,在一个应用程序中某个activity会被指定为“main activity"(主要活动),它在用户第一次启动应用程序时首先运行。这之后的每个activity都可以启动别的activity去完成各种行为。每次当一个新的activity启动时,之前的activity被停止,但是android系统会将它保存进一个堆栈(传说中的活动栈)。当一个新的activity启动时,它被压入活动栈,而且获得用户焦点。活动栈遵循基本的”后进先出”的队列机制,所以,当用户完成在当前activity的行为,并且按下BACK键后,它从栈中弹出(而且销毁),然后它之前的activity恢复运行。(活动栈在之后and Back Stack)文档会有更详细的讨论。)

When an activity is stopped because a new activity starts, it is notified of this change in state through the activity's lifecycle callback methods. There are several callback methods that an activity might receive, due to a change in its state—whether the system is creating it, stopping it, resuming it, or destroying it—and each callback provides you the opportunity to perform specific work that's appropriate to that state change. For instance, when stopped, your activity should release any large objects, such as network or database connections. When the activity resumes, you can reacquire the necessary resources and resume actions that were interrupted. These state transitions are all part of the activity lifecycle.

当一个activity由于新activity的启动而被停止时,它会被系统通知它这种状态的改变,通过activity生命周期回调函数。根据一个activity状态变化的不同(系统是在创建它,停止它,恢复它还是销毁它),它会收到不同的回调函数。每个回调函数给用户提供了一个接口去完成特定的与状态改变相适应的工作。比如,当停止activity时,你应该释放所有的大的对象,比如网络连接或者数据库连接的对象。当恢复activity时,你可以重新获得有关此activity必要的资源和恢复此activity被终止的行为。这些状态之间的转换就是activity的生命周期。

The rest of this document discusses the basics of how to build and use an activity, including a complete discussion of how the activity lifecycle works, so you can properly manage the transition between various activity states.

这篇文档的剩余部分讨论的是:怎么建立和使用一个activity,还包括一个关于activity生命周期怎么工作的完全的讨论,这样你就可以准确的掌握在不同activity状态之间的转换。

Creating an Activity

创建一个Activity

To create an activity, you must create a subclass of Activity (or an existing subclass of it). In your subclass, you need to implement callback methods that the system calls when the activity transitions between various states of its lifecycle, such as when the activity is being created, stopped, resumed, or destroyed. The two most important callback methods are:

创建一个activity,你必须创建Activity(或者它的一个已经存在的子类)的一个子类。在你的子类里,你需要实现那些回调函数,当activity状态在生命周期的不同状态之间改变(比如activity被创建,停止,恢复或者销毁)时,系统会调用这些回调函数。其中最重要的两个回调函数是:

onCreate()
You must implement this method. The system calls this when creating your activity. Within your implementation, you should initialize the essential components of your activity. Most importantly, this is where you must call  setContentView() to define the layout for the activity's user interface.
onCreate()
你必须实现这个方法。当创建activity时系统调用此方法。在你的实现中,你应该初始化你的activity必要的一些元素。最重要的是,在此方法中,你必须调用setContentView()来指定activity的用户界面的布局。
onPause()
The system calls this method as the first indication that the user is leaving your activity (though it does not always mean the activity is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back).
onPause()
系统调用此方法时,说明用户有离开你的activity的最初的迹象(然而这并不一定总是意味着你的activity即将被销毁)。通常在这儿,你应该保存下当前用户会话之前产生的所有变动(因为用户也许不会再回到此activity)。

There are several other lifecycle callback methods that you should use in order to provide a fluid user experience between activities and handle unexpected interuptions that cause your activity to be stopped and even destroyed. All of the lifecycle callback methods are discussed later, in the section about Managing the Activity Lifecycle.

还有几个其他的你应该使用的生命周期回调函数,这样当在不同activity之间转换,以及处理未预料的中断导致你的activity停止甚至是销毁时,可以提供一个流畅的用户体验。所有的生命周期回调函数都将在下文讨论,在关于Managing the Activity Lifecycle的部分。

Implementing a user interface

实现一个用户界面

The user interface for an activity is provided by a hierarchy of views—objects derived from the View class. Each view controls a particular rectangular space within the activity's window and can respond to user interaction. For example, a view might be a button that initiates an action when the user touches it.

一个activity的用户界面是由一些不同层次的views(一些继承View类的对象)来实现的。每个view控制一个特定的矩形区域,当然它在activity的窗口里,而且可以对用户的交互作出回应。比如,一个view也许是一个按钮,当用户触摸它时,开始某个行为。

Android provides a number of ready-made views that you can use to design and organize your layout. "Widgets" are views that provide a visual (and interactive) elements for the screen, such as a button, text field, checkbox, or just an image. "Layouts" are views derived from ViewGroup that provide a unique layout model for its child views, such as a linear layout, a grid layout, or relative layout. You can also subclass the View and ViewGroup classes (or existing subclasses) to create your own widgets and layouts and apply them to your activity layout.

Android提供相当数量的已经做好的view,你可以直接使用它们来设计和组织你的布局。“Widgets(窗口小部件)”是给窗口提供一些可视的(也是可交互的)元素,例如按钮,文字区域,单选框或仅仅是一张图片。“Layouts(布局)”继承自ViewGroup,为子视图提供一个独特的模型,它有线性布局,网格布局,相对布局等。你也可以创建View和ViewGroup的子类,去创建你自己的widgets和layouts,然后将它们应用到你的activity布局中。

The most common way to define a layout using views is with an XML layout file saved in your application resources. This way, you can maintain the design of your user interface separately from the source code that defines the activity's behavior. You can set the layout as the UI for your activity with setContentView(), passing the resource ID for the layout. However, you can also create new Views in your activity code and build a view hierarchy by inserting new Views into a ViewGroup, then use that layout by passing the root ViewGroup to setContentView().

使用views完成一个布局的最常见的方式是使用xml布局文件,它保存在你的应用程序资源里。这样,你可以将你设计的用户界面与确定activity行为的源码分离开来维护。你可以使用setContentView()来设置你的activity的UI布局,传递的参数是布局的资源ID。当然,你也可以在你的activity代码里创建新的views,在一个ViewGroup里建立一个分层的views,然后通过传递根ViewGroup到setContentView()来使用这个布局。

For information about creating a user interface, see the User Interface documentation.

想了解创建一个用户界面的更多信息,去看User Interface文档。

Declaring the activity in the manifest

在manifest里声明一个activity

You must declare your activity in the manifest file in order for it to be accessible to the system. To decalare your activity, open your manifest file and add an <activity> element as a child of the<application> element. For example:

你必须要在manifest文件里声明你的activity,这样它对系统来说才是可访问的。要声明你的activity,打开manifest文件,增加一个作为<application>叶子的<activity>元素。例如:

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

There are several other attributes that you can include in this element, to define properties such as the label for the activity, an icon for the activity, or a theme to style the activity's UI. See the<activity> element reference for more information about available attributes.

有好几个其他的属性可以包含在这个元素里,比如activity的标签,图标,activity的UI的主题样式等。看<activity>获得更多可用属性的信息。

Using intent filters

使用intent过滤器

An <activity> element can also specify various intent filters—using the <intent-filter> element—in order to declare how other application components may activate it.

一个<activity>元素也可以指定各种intent过滤器————使用<intent-filter>元素————声明别的应用组件怎样可以激活它。

When you create a new application using the Android SDK tools, the stub activity that's created for you automatically includes an intent filter that declares the activity responds to the "main" action and should be placed in the "launcher" category. The intent filter looks like this:

当你使用Android SDK tools创建一个新的应用程序时,自动创建的根activity包括一个intent过滤器,它声明这个activity负责回应“main”动作,而且应该被放在“launcher”目录里。这个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>

The <action> element specifies that this is the "main" entry point to the application. The <category> element specifies that this activity should be listed in the system's application launcher (to allow users to launch this activity).

上面的<action>元素说明了这个activity是“主要的”应用程序入口点。<category>元素说明了这个activity应该被列在系统的应用运行包(这样就允许用户运行这个activity)里。

If you intend for your application to be self-contained and not allow other applications to activate its activities, then you don't need any other intent filters. Only one activity should have the "main" action and "launcher" category, as in the previous example. Activities that you don't want to make available to other applications should have no intent filters and you can start them yourself using explicit intents (as discussed in the following section).

如果你希望你的应用是封闭独立的,不允许别的应用来激活它的activities,那么你不需要任何别的intent过滤器。只有一个activity会有“main"动作和”launcher“种类这两个属性,如之前的例子所展示的。对于那些你不希望它们对别的应用程序可见的activities,它们就不应该有intent过滤器。而你可以使用明确的intents来启动这些actvities(在下一部分会讨论)。

However, if you want your activity to respond to implicit intents that are delivered from other applications (and your own), then you must define additional intent filters for your activity. For each type of intent to which you want to respond, you must include an <intent-filter> that includes an <action> element and, optionally, a <category> element and/or a <data> element. These elements specify the type of intent to which your activity can respond.

但是,如果你希望你的activity响应那些含蓄的intents(它们来自于别的应用程序或者你自己的),那么你必须为你的activity指定额外的intent过滤器。对于每种你想要回应的intent,你必须增加一个包含<action>元素的<intent-filter>,还有两个可选的元素<category>,<data>.这些元素指定了你的activity可以响应的intent类型。

For more information about how your activities can respond to intents, see the Intents and Intent Filters document.

更多关于你的activity可以响应的intent信息,请看Intents and Intent Filters文档。

Starting an Activity

开始一个Activity

You can start another activity by calling startActivity(), passing it an Intent that describes the activity you want to start. The intent specifies either the exact activity you want to start or describes the type of action you want to perform (and the system selects the appropriate activity for you, which can even be from a different application). An intent can also carry small amounts of data to be used by the activity that is started.

你可以在一个activity里通过调用startActivity()来开始另一个activity,向此方法传递一个intent,描述你想开始哪个activity。intent可以精确的指定你想启动的activity或者只是描述你想实现的动作的类型(然后系统会选择合适的activity,它甚至可以来源于别的应用程序)。一个intent也可以携带少量的数据,供新启动的activity使用。

When working within your own application, you'll often need to simply launch a known activity. You can do so by creating an intent that explicitly defines the activity you want to start, using the class name. For example, here's how one activity starts another activity named SignInActivity:

当运行你的应用程序时,你会经常需要去运行一个已知的activity。你可以通过创建一个intent来完成,此intent使用activity的类名来精确地指定你想启动哪个activity。例如,下面展示了一个activity怎么启动另外一个名为SignInActivity的activity。

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

However, your application might also want to perform some action, such as send an email, text message, or status update, using data from your activity. In this case, your application might not have its own activities to perform such actions, so you can instead leverage the activities provided by other applications on the device, which can perform the actions for you. This is where intents are really valuable—you can create an intent that describes an action you want to perform and the system launches the appropriate activity from another application. If there are multiple activities that can handle the intent, then the user can select which one to use. For example, if you want to allow the user to send an email message, you can create the following intent:

有时候,你的应用也许还想完成某些动作,比如发送Email,文本信息或者升级状态,这其中会用到你的activity生成的一些数据。这种情况下,你的应用也许并没有自己的activity去完成这些动作,所以你可以使用设备上其他应用提供的activity,来帮你完成那些动作。这是intent真正非常有价值的地方——你可以创建一个intent,描述你想完成的动作,然后系统会从某一个应用里找到那个恰恰合适的activity,并运行它。如果有很多的activity可以处理这个intent,那么用户可以选择使用哪个。比如,如果你想允许用户发送一条email信息,你可以如下创建一个intent:

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

The EXTRA_EMAIL extra added to the intent is a string array of email addresses to which the email should be sent. When an email application responds to this intent, it reads the string array provided in the extra and places them in the "to" field of the email composition form. In this situation, the email application's activity starts and when the user is done, your activity resumes.

EXTRA_E MAIL这个附加到intent的额外信息,是一个字符数组,描述Email该被送往哪里。当有一个Email应用回应这个intent,它首先从附加信息里读取这个字符数组,将它放到一封Email信件的“送往"字段。这样,Email应用程序启动,然后当它完成后,你的activity恢复运行。

Starting an activity for a result

开始一个activity,并获取其返回值

Sometimes, you might want to receive a result from the activity that you start. In that case, start the activity by calling startActivityForResult() (instead of startActivity()). To then receive the result from the subsequent activity, implement the onActivityResult() callback method. When the subsequent activity is done, it returns a result in an Intent to youronActivityResult() method.

有时,你也许想要从你启动的activity里获得一个返回值。这种情况下,调用startActivityForResult() (而不是之前的startActivity())开始这个activity.要获得从子activity里返回的结果,实现这个回调方法:onActivityResult() .当子activity结束后,它返回一个包含结果的intent,到你刚实现的onActivityResult()方法。

For example, perhaps you want the user to pick one of their contacts, so your activity can do something with the information in that contact. Here's how you can create such an intent and handle the result:

例如,也许你会想要用户选中他的某个联系人,这样你的activity就可以使用这个联系人的数据。下面演示了你怎么创建这样的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);
}

@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...
        }
    }
}

This example shows the basic logic you should use in your onActivityResult() method in order to handle an activity result. The first condition checks whether the request was successful—if it was, then the resultCode will be RESULT_OK—and whether the request to which this result is responding is known—in this case, the requestCode matches the second parameter sent withstartActivityForResult(). From there, the code handles the activity result by querying the data returned in an Intent (the data parameter).

上例展示了想要处理activity的返回值,在你的onActivityResult()中你应该使用的基本逻辑。其中第一个if语句块,首先检查的是查询联系人是否成功——如果是,resultCode就是RESULT_OK——以及检查返回值要送达的查询人是否已知——如果是,requestCode就应该和startActivityForResult()中第二个参数相同。以上两条都通过以后,之后的代码就是对返回值data的处理,通过查询返回的intent里的data数据(即data这个参数)。

What happens is, a ContentResolver performs a query against a content provider, which returns a Cursor that allows the queried data to be read. For more information, see the Content Providers document.

具体来说,一个ContentResolver对象查询了一个content provider对象,provider对象返回一个指针,用于读取被查询的数据。更多信息,请看ContentProvider文档。

For more information about using intents, see the Intents and Intent Filters document.

关于使用intents的更多信息,请看Intents and Intent Filters文档。

Shutting Down an Activity

关闭一个Activity

You can shut down an activity by calling its finish() method. You can also shut down a separate activity that you previously started by calling finishActivity().

你可以通过调用finish()方法来关闭一个activity。你也可以通过调用finishActivity()来关闭你之前启动的某个特定activity。

Note: In most cases, you should not explicitly finish an activity using these methods. As discussed in the following section about the activity lifecycle, the Android system manages the life of an activity for you, so you do not need to finish your own activities. Calling these methods could adversely affect the expected user experience and should only be used when you absolutely do not want the user to return to this instance of the activity.

注意:绝大多数情况下,你不应该显示的使用这些方法来结束一个activity。如同下文对于activity的生命周期讨论过的一样,Android系统会为你管理activity的生命周期,所以你不必要结束你的activity。相反调用这些方法可能会影响到预期的用户体验。所以只有当你绝对十分完全肯定的不想用户回到你的这个activity,才推荐使用这些方法。

Managing the Activity Lifecycle

管理Activity的生命周期

Managing the lifecycle of your activities by implementing callback methods is crucial to developing a strong and flexible application. The lifecycle of an activity is directly affected by its association with other activities, its task and back stack.

通过之前介绍过的回调函数管理activity的生命周期是非常重要的,尤其是想创建一个强壮灵活的应用程序。一个activity的生命周期直接受到以下几个因素的影响:它和别的activity的交互,它的任务和活动栈。

An activity can exist in essentially three states:

一个activity最终要的几个状态:

Resumed
The activity is in the foreground of the screen and has user focus. (This state is also sometimes referred to as "running".)
activity在屏幕的前景中,而且获得用户焦点。
Paused
Another activity is in the foreground and has focus, but this one is still visible. That is, another activity is visible on top of this one and that activity is partially transparent or doesn't cover the entire screen. A paused activity is completely alive (the  Activity object is retained in memory, it maintains all state and member information, and remains attached to the window manager), but can be killed by the system in extremely low memory situations.
另一个activity在前景而且获得用户焦点,但是这个仍然处于可见状态。也就是,可以看见另一个activity在这个activity的上面,由于另一个是部分透明的或者不是全屏的原因。一个处于暂停状态的activity完全是活的(活的是指,这个activity对象仍然占据内存,它保持着所有的状态和成员信息,而且仍然从属于window manager),但是在系统内存及其低的情况下,可以被杀死。
Stopped
The activity is completely obscured by another activity (the activity is now in the "background"). A stopped activity is also still alive (the  Activity object is retained in memory, it maintains all state and member information, but is  not attached to the window manager). However, it is no longer visible to the user and it can be killed by the system when memory is needed elsewhere.
activity完全的被另一个activity覆盖(activity处于后景中)。一个停止的activity也仍然是活的(同上)。但是,它对用户来说已经是不可见的,当系统别的地方需要内存时,它就可以被杀死。

If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When the activity is opened again (after being finished or killed), it must be created all over.

当一个activity处于暂停或者停止态时,系统从内存回收它,既可以命令它结束(通过调用它的finish()方法),也可以简单的杀死它的进程。当activity再一次被开始(在它结束或者被杀死之后),它必须从头到脚的重新创建。

Implementing the lifecycle callbacks

实现生命周期回调函数

When an activity transitions into and out of the different states described above, it is notified through various callback methods. All of the callback methods are hooks that you can override to do appropriate work when the state of your activity changes. The following skeleton activity includes each of the fundamental lifecycle methods:

当一个activity在上面描述的各种状态之间转换时,它会通知这么多的回调函数。所有的回调函数都可看作是一个钩子,你可以覆盖它们来完成合适的工作,在activity状态变换时调用之。下面的这个框架activity包含了每一个基础的生命周期回调函数:

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.
    }
}

Note: Your implementation of these lifecycle methods must always call the superclass implementation before doing any work, as shown in the examples above.

注意:你对这些回调函数的实现,必须总是首先要调用父类的实现,在你任何的具体工作之前。如同上面的例子中,super.onXXXX().

Taken together, these methods define the entire lifecycle of an activity. By implementing these methods, you can monitor three nested loops in the activity lifecycle:

总体来说,这些方法决定了一个activity的整个生命周期。通过实现这些方法,你可以监测到在activity生命周期里三个嵌套的循环。

  • The entire lifetime of an activity happens between the call to onCreate() and the call to onDestroy(). Your activity should perform setup of "global" state (such as defining layout) inonCreate(), and release all remaining resources in onDestroy(). For example, if your activity has a thread running in the background to download data from the network, it might create that thread in onCreate() and then stop the thread in onDestroy().
  • activity的整个生命是从onCreate()开始到onDestroy()结束。你的activity应该在onCreate()方法里完成一些全局状态的实现(比如决定activity的布局),而在onDestroy()里释放所有仍在的资源。例如,如果你的activity在后台运行了一个从网上下载数据的线程,它也许就在onCreate()里创建,而在onDestroy()里停止。
  • The visible lifetime of an activity happens between the call to onStart() and the call to onStop(). During this time, the user can see the activity on-screen and interact with it. For example,onStop() is called when a new activity starts and this one is no longer visible. Between these two methods, you can maintain resources that are needed to show the activity to the user. For example, you can register a BroadcastReceiver in onStart() to monitor changes that impact your UI, and unregister it in onStop() when the user can no longer see what you are displaying. The system might call onStart() and onStop() multiple times during the entire lifetime of the activity, as the activity alternates between being visible and hidden to the user.

    activity处于可见的生命周期从onStart()开始,到onStop()结束。在这段时间里,用户可以在屏幕上看见此activity,而且可与之交互。比如,当一个新的activity启动,旧的activty的onStop()方法就被调用,它也不再为可见的了。在这两个方法时间之内,你可以保持有让用户看见此activity所必须的资源。比如,你可以在onStart()里注册一个BroadcastReceiver,来监视影响你的UI的变动,而在用户已经看不见界面的onStop()方法里撤销注册。在一个activity的整个生命周期里,系统也许会多次调用onStart()和onStop()方法,当这个activity不断的在用户可见和不可见之间来回转换时。

  • The foreground lifetime of an activity happens between the call to onResume() and the call to onPause(). During this time, the activity is in front of all other activities on screen and has user input focus. An activity can frequently transition in and out of the foreground—for example, onPause() is called when the device goes to sleep or when a dialog appears. Because this state can transition often, the code in these two methods should be fairly lightweight in order to avoid slow transitions that make the user wait.

    activity处于后台状态的生命周期从onPause()开始,onResume()结束。在这段时间里,此activity在屏幕上所有其他activity的前面,而且获得用户焦点。一个activity可以频繁的在前台和后台之间切换——比如,onPuase()在设备休眠或者一个对话框消失的时候被调用。由于这种状态可以经常转换,这两个方法中的代码应该为轻量级的,以避免转换过慢,让用户等待。

Figure 1 illustrates these loops and the paths an activity might take between states. The rectangles represent the callback methods you can implement to perform operations when the activity transitions between states.



Figure 1. The activity lifecycle.

The same lifecycle callback methods are listed in table 1, which describes each of the callback methods in more detail and locates each one within the activity's overall lifecycle, including whether the system can kill the activity after the callback method completes.

生命周期回调函数都列在表1中,此表具体的描述了每个回调函数的细节,并在一个activity的整个生命周期中定位每一个函数,也包括了当回调函数完成之后,系统能否杀死此activity的信息。

Table 1. A summary of the activity lifecycle's callback methods.

Method Description Killable after? Next
onCreate() Called when the activity is first created. This is where you should do all of your normal static set up — create views, bind data to lists, and so on. This method is passed a Bundle object containing the activity's previous state, if that state was captured (see Saving Activity State, later).

Always followed by onStart().

No onStart()
  onRestart() Called after the activity has been stopped, just prior to it being started again.

Always followed by onStart()

No onStart()
onStart() Called just before the activity becomes visible to the user.

Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.

No onResume() 
or
onStop()
  onResume() Called just before the activity starts interacting with the user. At this point the activity is at the top of the activity stack, with user input going to it.

Always followed by onPause().

No onPause()
onPause() Called when the system is about to start resuming another activity. This method is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, and so on. It should do whatever it does very quickly, because the next activity will not be resumed until it returns.

Followed either by onResume() if the activity returns back to the front, or by onStop() if it becomes invisible to the user.

Yes onResume() 
or
onStop()
onStop() Called when the activity is no longer visible to the user. This may happen because it is being destroyed, or because another activity (either an existing one or a new one) has been resumed and is covering it.

Followed either by onRestart() if the activity is coming back to interact with the user, or byonDestroy() if this activity is going away.

Yes onRestart()
or
onDestroy()
onDestroy() Called before the activity is destroyed. This is the final call that the activity will receive. It could be called either because the activity is finishing (someone called finish() on it), or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method. Yes nothing

The column labeled "Killable after?" indicates whether or not the system can kill the process hosting the activity at any time after the method returns, without executing another line of the activity's code. Three methods are marked "yes": (onPause()onStop(), and onDestroy()). Because onPause() is the first of the three, once the activity is created, onPause() is the last method that's guaranteed to be called before the process can be killed—if the system must recover memory in an emergency, then onStop() and onDestroy() might not be called. Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage. However, you should be selective about what information must be retained during onPause(), because any blocking procedures in this method block the transition to the next activity and slow the user experience.

标签为“Killable after”的列描述了当函数返回后的某个时间,系统能否杀死作为activity宿主的进程,且不用执行activity的额外一行代码(译者注:指activity.finish())。有3个被标记为“yes”的方法:(onPause()onStop(), 和 onDestroy() )。因为onPause()是3个中第一个被执行的,一旦一个activity被创建,onPause()是在进程可以被杀死前最后一个保证能被执行的方法——如果系统需要紧急回收内存,那么onStop()和onDestroy()也许不会再被执行。因此,你应该使用onPause()来将持续存在的数据(比如用户信用卡信息)写入存储区。但是,你应该有选择的保存那些在onPause()中必须被保存的信息,因为在这个函数里,任何成块的程序段都有可能影响此activity转到下一个activity,从而降低用户体验。

Methods that are marked "No" in the Killable column protect the process hosting the activity from being killed from the moment they are called. Thus, an activity is killable from the timeonPause() returns to the time onResume() is called. It will not again be killable until onPause() is again called and returns.

Killable列被标记为“No”的函数一旦被调用,就会保护作为activity宿主的进程不被杀死。因此,一个activity处于可被杀死的状态,是从onPause()返回时,到onResume()被调用时。直到下一次调用onPause()而且从它返回之前,此activity都不能被杀死。

Note: An activity that's not technically "killable" by this definition in table 1 might still be killed by the system—but that would happen only in extreme circumstances when there is no other recourse. When an activity might be killed is discussed more in the Processes and Threading document.

注意:如果存在一个activity,根据表1的规则它是不可被杀死的,实际上仍然可能会被系统杀死——但是这只在非常极端的境况——即系统完全没有其他的资源——下,才可能发生。何时一个activity可能会被杀死的更多信息,请看Process and Threading文档。

Saving activity state

保存activtiy状态

The introduction to Managing the Activity Lifecycle briefly mentions that when an activity is paused or stopped, the state of the activity is retained. This is true because the Activity object is still held in memory when it is paused or stopped—all information about its members and current state is still alive. Thus, any changes the user made within the activity are retained in memory, so that when the activity returns to the foreground (when it "resumes"), those changes are still there.

Managing the Activity Lifecycle的介绍简要的提到了当一个activity处于暂停或者停止状态时,它的状态信息仍然被保存着。这是因为当一个activity对象暂停或者停止时,它仍然保存在内存里——关于它的所有成员的信息和当前状态都仍然健在。因此,用户之前在activity里做的任何变动都保存在内存里,这样当activity返回到前台(即执行onResume()),这些变动仍然还在。

Figure 2. The two ways in which an activity returns to user focus with its state intact: either the activity is stopped, then resumed and the activity state remains intact (left), or the activity is destroyed, then recreated and the activity must restore the previous activity state (right).

However, when the system destroys an activity in order to recover memory, theActivity object is destroyed, so the system cannot simply resume it with its state intact. Instead, the system must recreate the Activity object if the user navigates back to it. Yet, the user is unaware that the system destroyed the activity and recreated it and, thus, probably expects the activity to be exactly as it was. In this situation, you can ensure that important information about the activity state is preserved by implementing an additional callback method that allows you to save information about the state of your activity and then restore it when the the system recreates the activity.

但是,当系统为了回收内存,销毁了一个activity时,此activity对象已被销毁,所以系统不能如同之前那样,简单地使用它的全部状态信息恢复运行它。实际上,系统会重建Activity对象,如果用户返回到这个activity。不过用户完全不知道系统已经销毁了activity而且重建了它。所以,也许系统会期望新建的activity和之前的完全一样。在这种情况下,你可以通过在之前的activity里实现一个额外的回调函数来保证此activity的重要状态信息被保存下来。这个回调函数可以让你保存有关你的activity状态的信息,然后当系统重建这个activity时恢复它。

The callback method in which you can save information about the current state of your activity is onSaveInstanceState(). The system calls this method before making the activity vulnerable to being destroyed and passes it a Bundle object. The Bundle is where you can store state information about the activity as name-value pairs, using methods such as putString(). Then, if the system kills your activity's process and the user navigates back to your activity, the system passes the Bundle to onCreate() so you can restore the activity state you saved duringonSaveInstanceState(). If there is no state information to restore, then theBundle passed to onCreate() is null.

用于保存activity当前状态信息的回调函数为:onSaveInstanceState()。系统在activity极易被销毁之前调用此函数,并向它传递一个Bundle对象。Bundle对象就是你保存activity状态信息的地方,它采用的是键值对的方式,使用类似putString()的方法。然后,如果系统杀死了你的activity的宿主进程,而且用户想回到你的activity,系统会将Bundle传递给onCreate(),这样你就可以恢复之前在onSaveInstanceState()里保存的activtiy状态信息了。如果没有状态信息可用于恢复,传递给onCreate()的Bundle将为空。

Note: There's no guarantee that onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won't be necessary to save the state (such as when the user leaves your activity using the BACK key, because the user is explicitly closing the activity). If the method is called, it is always called before onStop() and possibly before onPause().

注意:没有谁能保证当你的activity被销毁时onSaveInstanceState()一定会被调用,因为存在某些情况,保存状态信息是没有必要的(比如用户使用BACK键来退出你的activity,因为毫无疑问,此时用户是想关闭这个activity)。如果此方法被调用,它总是在onStop()之前,可能在onPause()之前被调用。

However, even if you do nothing and do not implement onSaveInstanceState(), some of the activity state is restored by the Activity class's default implementation of onSaveInstanceState(). Specifically, the default implementation calls onSaveInstanceState() for every View in the layout, which allows each view to provide information about itself that should be saved. Almost every widget in the Android framework implements this method as appropriate, such that any visible changes to the UI are automatically saved and restored when your activity is recreated. For example, the EditText widget saves any text entered by the user and the CheckBox widget saves whether it's checked or not. The only work required by you is to provide a unique ID (with the android:id attribute) for each widget you want to save its state. If a widget does not have an ID, then it cannot save its state.

但是,即使你什么都不做,也不实现onSaveInstanceState()方法,有些activity状态仍然会通过Activity类中onSaveInstanceState()的默认实现而保存下来。这种特殊情况下,默认实现为布局的每一个View调用onSaveInstanceState()方法,允许每个view提供关于它自己的应该被保存的信息。几乎在Android框架中所有的widget都相应地实现了这个方法,所以用户界面上任何可视的变动都会自动保存,而且当你的activity被创建时恢复。比如文本编辑框widget保存任何用户输入的文本信息,单选框widget保存了它是否被选中的信息。你唯一要做的事情就是给每个你想保存它的状态的widget提供一个唯一的ID(使用android:id属性)。如果一个widget没有ID,它将不能保存它的状态。

Although the default implementation of onSaveInstanceState() saves useful information about your activity's UI, you still might need to override it to save additional information. For example, you might need to save member values that changed during the activity's life (which might correlate to values restored in the UI, but the members that hold those UI values are not restored, by default).

尽管onSaveInstanceState()的默认实现保存了关于你的activity用户界面的有用信息,你也许仍然需要覆盖这个函数,去保存额外的信息。比如,你也许需要保存一些在activity生命周期中发生变化的成员值(这些成员值也许与用户界面保存的一些属性值保持一致,但是默认情况下,持有用户界面属性的这些成员值并没有被保存。)

Because the default implementation of onSaveInstanceState() helps save the state of the UI, if you override the method in order to save additional state information, you should always call the superclass implementation of onSaveInstanceState() before doing any work.

由于onSaveInstanceState()的默认实现已经帮助保存了一些UI状态信息,所以如果你为了保存额外的信息需要覆盖这个方法时,你总是应该首先调用onSaveInstanceState()的父类(即super.onSaveInstanceState():译者注)。

Note: Because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity.

注意:因为onSaveInstanceState()并不保证一定能被调用,所以你应该仅仅使用它来记录那些activity临时的数据——你决不应该用它来保存持久的数据。作为替代,当用户离开你的activity时,你应该使用onPause()来保存持久数据(比如需要被保存进数据库的数据)。

A good way to test your application's ability to restore its state is to simply rotate the device so that the screen orientation changes. When the screen orientation changes, the system destroys and recreates the activity in order to apply alternative resources that might be available for the new orientation. For this reason alone, it's very important that your activity completely restores its state when it is recreated, because users regularly rotate the screen while using applications.

要测试你的应用程序保存状态信息的能力,有一个简单又好的方法:旋转设备,改变屏幕的方向。当屏幕方向变化时,系统销毁activity,然后重建它,为了申请变化的在新的朝向中也许可用的资源。仅仅是为了这一个理由,你的activity在重建时完全的保存它的状态信息,就显得非常重要。因为用户使用各种应用时,经常会旋转屏幕。

Handling configuration changes

处理配置变化

Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (onDestroy() is called, followed immediately by onCreate()). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that you've provided. If you design your activity to properly handle this event, it will be more resilient to unexpected events in the activity lifecycle.

设备的有些配置在运行时可能会发生变化(比如屏幕方向的变化,键盘是否可用,语言等)。当这样的变化发生时,Android重启正在运行的Activity(先调用onDestroy(),然后立即运行onCreate())。这个重启行为的设计,是为了帮助你的应用程序与新的配置保持一致,使用你之前提供的变化的资源,系统自动重新载入你的应用程序。如果在设计你的activity时,你可以恰当的处理这个事件,你的activity在整个生命周期里,遇到未预料的事件时的弹性就更强(就是更健壮)。

The best way to handle a configuration change, such as a change in the screen orientation, is to simply preserve the state of your application using onSaveInstanceState() andonRestoreInstanceState() (or onCreate()), as discussed in the previous section.

处理一个配置变化(比如屏幕方向的变化)的最好方式,是简单地使用 onSaveInstanceState() 和onRestoreInstanceState() (或 onCreate())来保存你的应用程序的状态信息,如上面一个部分讨论的那样。

For a detailed discussion about configuration changes that happen at runtime and how you should handle them, read Handling Runtime Changes.

关于运行时的配置变化以及你应该怎样处理它,更多信息请看Handling Runtime Changes。

Coordinating activities

多activity协调工作

When one activity starts another, they both experience lifecycle transitions. The first activity pauses and stops (though, it won't stop if it's still visible in the background), while the other activity is created. In case these activities share data saved to disc or elsewhere, it's important to understand that the first activity is not completely stopped before the second one is created. Rather, the process of starting the second one overlaps with the process of stopping the first one.

当一个activity开启另一个时,他们都会经历生命周期的变化。第一个activity暂停和停止(当然如果它在背景中仍然可见,它不会被停止),而另一个activity被创建。有一种情况下,比如这些activity共享那些保存到磁盘或者别处的数据,理解这样一个事实——即在第二个activity被创建时,第一个activity还没有完全停止——非常重要。实际上,开启第二个activtity的进程和停止第一个的进程在时间上部分重叠。

The order of lifecycle callbacks is well defined, particularly when the two activities are in the same process and one is starting the other. Here's the order of operations that occur when Activity A starts Acivity B:

声明周期回调函数的顺序已经很好的被预定义了,即使是这样的特殊情况,两个activity处于同一个进程,一个启动另外一个。下面是当Activity A启动Activity B时,产生的操作的顺序:

  1. Activity A's onPause() method executes.
  2. Activity B's onCreate()onStart(), and onResume() methods execute in sequence. (Activity B now has user focus.)
  3. Then, if Activity A is no longer visible on screen, its onStop() method executes.

   1.执行Activity A的onPause()方法。

   2.Activity B的onCreate(), onStart() 和onResume()方法顺序得到执行。(Activity B此时获得用户焦点。)

   3.然后,如果Activity A 在屏幕上不再可见,它的onStop()方法开始执行。

This predictable sequence of lifecycle callbacks allows you to manage the transition of information from one activity to another. For example, if you must write to a database when the first activity stops so that the following activity can read it, then you should write to the database during onPause() instead of during onStop().

由于这个生命周期回调函数的执行顺序完全可知,你可以管理从一个activity到另一个activity的转换信息。比如,如果在第一个activity停止时,你必须向数据库写入数据,以方便第二个activity来读它,那么你应该在onPause()而不是onStop()时,将数据写入数据库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值