Android Activities 文档专题

来源:互联网 发布:数据仓库软件 编辑:程序博客网 时间:2024/05/20 07:32

内容目录

Creatingan Activity窗口的创建 2

Implementinga user interface实现用户接口/使用界面 3

Declaringthe activity in the manifestmanifest文件中申明activity 4

Usingintent filters使用意图过滤器 4

Startingan Activity启动窗口 6

Startingan activity for a result启动返回数据的窗口 7

ShuttingDown an Activity关闭窗口 8

Managingthe Activity Lifecycle管理窗口的生命周期 8

Implementingthe lifecycle callbacks实现生命周期回调方法 9

Savingactivity state 14

时间: 16

翻译原因: 16

感谢: 16

作者:tops 17



Activities窗口/活动

An Activity isan application component that provides a screen with which users caninteract in order to do something, such as dial the phone, take aphoto, send an email, or view a map. Each activity is given a windowin which to draw its user interface. The window typically fills thescreen, but may be smaller than the screen and float on top of otherwindows.

窗口是一个应用程序的组件,它提供一个与用户交互的屏幕,比如拨打电话、照照片、发电子邮件、查看地图。每一个窗口提供一个视窗来放置它的用户接口。一般的视窗充满了屏幕,但是也有可能比屏幕小的、漂浮在其他视窗之上。

Anapplication usually consists of multiple activities that are looselybound to each other. Typically, one activity in an application isspecified as the "main" activity, which is presented to theuser when launching the application for the first time. Each activitycan then start another activity in order to perform differentactions. Each time a new activity starts, the previous activity isstopped, but the system preserves the activity in a stack (the "backstack"). When a new activity starts, it is pushed onto the backstack and takes user focus. The back stack abides to the basic "lastin, first out" stack mechanism, so, when the user is done withthe current activity and presses the Back button,it is popped from the stack (and destroyed) and the previous activityresumes. (The back stack is discussed more in the Tasksand Back Stack document.)

一个应用程序通常由多个窗口组成,多个窗口相互松散地绑定在一起。一般地,有一个窗口在应用程序里被指定为“主”窗体,它在用户启动应用程序时第一个出现在用户面前的。每一个窗口都可以为了展现不同的动作而随后开启其他的窗口。每当一个新窗口启动,前一个窗口就被停止了,但是系统将窗口保存在了一个堆栈中(回退栈)。当一个新窗口被启动,它便被推到回退栈中并获得焦点。回退栈遵循着基本的“后进先出”堆栈机制,所以,当用户用完了当前窗口并按下“返回按钮,当前窗口将被弹出回退栈(并被销毁),(回退栈中)前一个窗口将重新使用。

Whenan activity is stopped because a new activity starts, it is notifiedof this change in state through the activity's lifecycle callbackmethods. There are several callback methods that an activity mightreceive, due to a change in its state—whether the system iscreating it, stopping it, resuming it, or destroying it—and eachcallback provides you the opportunity to perform specific work that'sappropriate to that state change. For instance, when stopped, youractivity should release any large objects, such as network ordatabase connections. When the activity resumes, you can reacquirethe necessary resources and resume actions that were interrupted.These state transitions are all part of the activity lifecycle.

当一个窗口因为另一个新的窗口启动而关闭,它通过窗口的生命周期回调方法,通知这种状态的改变。因为状态的改变,窗口可以接收很多个回调方法,这种状态的改变有可能是系统创建它、停止它(不可见)、重新使用(可见)、或者销毁它。每一个回调方法都提供给你一个展示特定工作的机会来适应窗口状态的改变。举例来说,当被停止,窗口应该会释放任何大型对象,比如网络或数据库的连接。当窗口重新被使用,你可以重新请求必须的资源,重新使用被中断的活动。这些状态转换时所有窗口生命周期的一部分。

Therest of this document discusses the basics of how to build and use anactivity, including a complete discussion of how the activitylifecycle works, so you can properly manage the transition betweenvarious activity states.

本文档接下来讨论的是如何简单地创建和使用一个窗口,其中包括了对窗口生命周期如何工作的完整讨论,所以你可以正确地管理多个窗口状态的转换了。

Creating anActivity窗口的创建

Tocreate an activity, you must create a subclass of Activity (oran existing subclass of it). In your subclass, you need to implementcallback methods that the system calls when the activity transitionsbetween various states of its lifecycle, such as when the activity isbeing created, stopped, resumed, or destroyed. The two most importantcallback methods are:

为了创建一个窗口,你必须创建一个Activity(或Activity子类)的子类。在你创建的子类中,当窗口在它生命周期中不同状态间转换时,比如当窗口被创建、停止、重新使用,或者被销毁的时候。你必须实现系统要用的回调方法。而两个最重要的回调方法是:

onCreate()
Youmust implement this method. The system calls this when creatingyour activity. Within your implementation, you should initializethe essential components of your activity. Most importantly, thisis where you must call setContentView() todefine the layout for the activity's user interface.
窗口的创建方法
你必须实现这个方法。系统会在创建你的窗口时调用此方法。在你的实现中,你必须初始化窗口所必须的组件。最重要的是, setContentView() 这个方法是你必须调用以定义窗口的布局的。
onPause()
Thesystem calls this method as the first indication that the user isleaving your activity (though it does not always mean the activityis being destroyed). This is usually where you should commit anychanges that should be persisted beyond the current user session(because the user might not come back).
窗口失去焦点的方法
当最先有有迹象表示用户离开了窗口,系统就会调用这个方法(调用过这个方法不一定就总是意味着窗口就会被销毁[注:销毁窗口时必须调用过此方法,即依次调用onPauseonStoponDestory])。在这个方法中,通常是你应该保存用户这段时间里所做的任何改变的时候,因为用户有可能不在回来了。

Thereare several other lifecycle callback methods that you should use inorder to provide a fluid user experience between activities andhandle unexpected interuptions that cause your activity to be stoppedand even destroyed. All of the lifecycle callback methods arediscussed later, in the section about Managingthe Activity Lifecycle.

还有一些其他的生命周期回调方法你应该使用,一来这样可以提供一个流畅的窗口用户体验。二来可以处理一些比如停止甚至销毁等动作导致的窗口中断。所有的生命周期回调方法会在接下来的 Managingthe Activity Lifecycle这一节中讨论。



Implementinga user interface实现用户接口/使用界面

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

一个窗口的使用界面是由层次化化的视图提供-这些对象都是源自于 View 类。每一个视图都控制着窗口内的一块特定区域并且对用户的交互做出反应。例如,一个视图可能是一个按钮,当用户触摸这个按钮时它执行一个动作。

Androidprovides a number of ready-made views that you can use to design andorganize your layout. "Widgets" are views that provide avisual (and interactive) elements for the screen, such as a button,text field, checkbox, or just an image. "Layouts" are viewsderived from ViewGroup thatprovide a unique layout model for its child views, such as a linearlayout, a grid layout, or relative layout. You can also subclassthe View and ViewGroupclasses(or existing subclasses) to create your own widgets and layouts andapply them to your activity layout.

Android提供了大量现成的视图供你设计或组织你的布局。“控件”是视图,被用来提供给屏幕一个可视化(并且可交互)的一个部分。例如按钮、文本框、复选框,或者图像显示区。”布局“是源自于视图组的视图,视图组给它的子视图类提供了一个独一无二的布局模型,比如线性布局、表格布局、相对布局。你也可以搞一个继承View或者ViewGroup、或者他们的子类的类来创建你自己的控件和布局,并且可以在你的窗口布局中使用他们。

Themost common way to define a layout using views is with an XML layoutfile saved in your application resources. This way, you can maintainthe design of your user interface separately from the source codethat defines the activity's behavior. You can set the layout as theUI for your activity with setContentView(),passing the resource ID for the layout. However, you can also createnew Viewsin your activity code and build a view hierarchy by insertingnew Viewsinto a ViewGroup,then use that layout by passing theroot ViewGroup tosetContentView().

最常用的定义视图为布局的方式是使用保存在应用程序资源目录内的XML布局文件。通过这种方式,你可以你可以保持你的用户界面设计与定义窗口行为的代码分离。你可以通过 setContentView()方法来设置布局文件的资源ID,然后让这种布局成为你窗口的用户界面。然而,你也可以在你的窗口代码中创建新的视图,也可以通过插入新视图到视图组来创建一个视图结构,然后通过setContentView()方法设置根视图组来使用这个布局。

Forinformation about creating a user interface, see the UserInterface documentation.

如何创建一个用户界面的信息, UserInterface 这篇文档

Declaringthe activity in the manifestmanifest文件中申明activity

Youmust declare your activity in the manifest file in order for it to beaccessible to the system. To declare your activity, open yourmanifest file and add an <activity> elementas a child of the <application> element.For example:

为了让系统使用你的窗口,你必须在manifest文件中通过以下方式申明,在manifest文件的<appliacation>元素下添加<activity>元素,例子如下:

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

Thereare several other attributes that you can include in this element, todefine properties such as the label for the activity, an icon for theactivity, or a theme to style the activity's UI.

你可以包含在activity元素里使用其他几个属性来定义比如窗口的标题、窗口的图标、或者窗口主题等特性。

The android:name attributeis the only required attribute—it specifies the class name of theactivity. Once you publish your application, you should not changethis name, because if you do, you might break some functionality,such as application shortcuts (read the blog post, ThingsThat Cannot Change).

 android:name 这个属性是必须要定义的,它明确定义了这个窗口的类名。一旦你发布了你的应用程序,你将不能更改这个名字,因为你一旦改了,有可能会损害一些功能。比如应用程序的快捷键,详细情况可阅读 ThingsThat Cannot Change这篇博客。

Seethe <activity> elementreference for more information about declaring your activity in themanifest.

查看 <activity> 元素的参考以获得更多在manifest文件中申明activity的信息。

Usingintent filters使用意图过滤器

An <activity> elementcan also specify various intent filters—usingthe <intent-filter> element—inorder to declare how other application components may activate it.

一个 <activity> 元素也可以使用 <intent-filter> 元素指定若干个意图过滤器,这样做是为了申明其他应用程序组件如何激活本窗口(使用本窗口)。

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

当你使用了AndroidSDK工具创建了一个新应用程序,它也会为你自动创建一个根窗口,并且它自动包含了意图过滤器,这个意图过滤器里申明了为”main“的动作和”launcher“的类别/范畴。这个意图过滤器就像下面这个这样:

<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> elementspecifies that this is the "main" entry point to theapplication.

 <action> 元素指定了这个窗口时进入应用程序的主窗口,(也就是启动应用程序后首先显示的窗口)

The <category> elementspecifies that this activity should be listed in the system'sapplication launcher (to allow users to launch this activity).

 <category> 元素指定这个窗口(的图标)必须被列在系统程序启动器的列表里,这是为了让用户启动这个窗口(启动应用程序)。

Ifyou intend for your application to be self-contained and not allowother applications to activate its activities, then you don't needany 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 otherapplications should have no intent filters and you can start themyourself using explicit intents (as discussed in the followingsection).

如果你倾向于让你的应用程序不被其他程序激活/访问,你就不需要指定其他意图过滤器了。只有一个窗口需要包含”main“的动作和”launcher“的范畴,就像前面的例子那样。你不想让其他程序访问的窗口没有意图过滤器,这时你可以在本程序内使用显式意图(explicitintents)访问他们,接下来就讨论它。

However,if you want your activity to respond to implicit intents that aredelivered from other applications (and your own), then you mustdefine additional intent filters for your activity. For each type ofintent to which you want to respond, you must includean <intent-filter> thatincludes an <action> elementand, optionally, a<category> elementand/or a <data> element.These elements specify the type of intent to which your activity canrespond.

然而,如果你想让你的窗口响应其他程序(包括你自己的程序)传递过来的隐式意图(implicitintents),你必须为窗口定义额外的意图过滤器。为了响应任何一种意图,你必须让窗口包含 <intent-filter> ,并且包含一个必须的 <action> 元素,和可选的<category><data>元素。这些元素指定了你的窗口可以响应那些种类的意图。

Formore information about how your activities can respond to intents,see the Intentsand Intent Filtersdocument.

关于窗口响应意图的更多信息,你可以参见 Intentsand Intent Filters

Startingan Activity启动窗口


Youcan start another activity by calling startActivity(),passing it an Intent thatdescribes the activity you want to start. The intent specifies eitherthe exact activity you want to start or describes the type of actionyou want to perform (and the system selects the appropriate activityfor you, which can even be from a different application). An intentcan also carry small amounts of data to be used by the activity thatis started.

你可以使用 startActivity()方法来启动另一个窗口,通过使用意图(Intent)参数来描述你想启动的窗口。这个意图精确地指定了你想启动的窗口或你想执行的动作(action)类型。如果指定活动类型,系统将选择恰当的一个窗口给你,这个窗口可以是来自不同程序的。一个意图也可以携带少量的数据给将要启动的窗口使用。

Whenworking within your own application, you'll often need to simplylaunch a known activity. You can do so by creating an intent thatexplicitly defines the activity you want to start, using the classname. For example, here's how one activity starts another activitynamed SignInActivity:

当在你自己的这个应用程序里工作时,你通常需要启动一个知道名字的窗口,这时你可以使用类名显式地定义一个意图来指定你想启动的窗口。例如,这是一个窗口如何用此方法启动另一个名叫 SignInActivity的窗口的:

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

However,your application might also want to perform some action, such as sendan email, text message, or status update, using data from youractivity. In this case, your application might not have its ownactivities to perform such actions, so you can instead leverage theactivities provided by other applications on the device, which canperform the actions for you. This is where intents are reallyvaluable—you can create an intent that describes an action you wantto perform and the system launches the appropriate activity fromanother application. If there are multiple activities that can handlethe 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 cancreate the following intent:

然而,你的应用程序可能执行一些像发送邮件、短信息、或者状态更新,或从你的窗口里获取数据的动作,在这种情况下,你的应用程序可能没有自己的窗口来执行这些动作,你需要充分使用设备上其他程序提供的窗口,它们可以为你执行那些动作。这也是意图的真正价值所在-你可以创建一个意图描述你想要执行的动作,系统从其他程序里为你启动恰当的窗口。如果有多个窗口处理意图,系统会给你一个选择列表,用户选择一个使用就好了。例如,如果你想让用户发送一个电子邮件,你可以创建如下意图:

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

The EXTRA_EMAIL extraadded to the intent is a string array of email addresses to which theemail should be sent. When an email application responds to thisintent, it reads the string array provided in the extra and placesthem in the "to" field of the email composition form. Inthis situation, the email application's activity starts and when theuser is done, your activity resumes.

其中 EXTRA_EMAIL 是额外给意图添加的字符串,用来指定电子邮件的收件地址。当一个邮件程序响应了此意图,它会读取添加的字符串并放在邮件的地址部分。在这种情况下,邮件应用程序的窗口启动并执行动作,之后你的窗口就重新可见。

Startingan activity for a result启动返回数据的窗口

Sometimes,you might want to receive a result from the activity that you start.In that case, start the activity bycalling startActivityForResult() (insteadof startActivity()).To then receive the result from the subsequent activity, implementthe onActivityResult() callbackmethod. When the subsequent activity is done, it returns a result inan Intent toyour onActivityResult() method.

有时候,你需要接收从你启动的窗口里返回的结果。这种情况下,可以使用 startActivity()的替代方法 startActivityForResult() 来启动窗口,接下来实现 onActivityResult() 这个回调方法来接收从后面的窗口返回的结果。当后面的窗口执行结束,它会通过一个意图将结果返回到 onActivityResult() 方法里。

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

例如,或许你想让用户从他们的联系人列表选择一个联系人,你的窗口可以对这个联系人的信息做一些处理。下面是如何创建一个这样的意图并处理结果:

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

Thisexample shows the basic logic you should use inyour onActivityResult() methodin order to handle an activity result. The first condition checkswhether the request was successful—if it was, thenthe resultCode willbe RESULT_OK—andwhether the request to which this result is responding is known—inthis case, the  requestCodematchesthe second parameter sent with  startActivityForResult().From there, the code handles the activity result by querying the datareturned in an Intent (the data parameter).

这个例子展示了一个基本的使用 onActivityResult() 方法处理窗口返回结果的逻辑。首先的条件检查请求是否成功,如果成功了,接下来检查结果码(resultCode)是 RESULT_OK---这一结果码的请求是否已知。如果请求码(requestCode)跟startActivityForResult()方法的第二个参数匹配。接下来的代码通过查询意图返回的数据来处理窗口返回结果,意图返回的数据是data参数。

Whathappens is, a ContentResolver performsa query against a content provider, which returns a Cursor thatallows the queried data to be read. For more information, seethe ContentProviders document.

实际发生的情况是, ContentResolver执行了对内容提供者(contentprovider)的查询,并返回了一个光标(Cursor,它允许查询的数据可以被读取。更多的信息,请查看 ContentProviders 的文档

Formore information about using intents, see the Intentsand Intent Filters document.

更多关于意图的信息,请查看意图与意图过滤器文档

Shutting Downan Activity关闭窗口


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

可以调用窗口的 finish() 方法关闭窗口。也可以使用 finishActivity()方法关闭你之前开启的一个不相关的窗口。

Note: Inmost cases, you should not explicitly finish an activity using thesemethods. As discussed in the following section about the activitylifecycle, the Android system manages the life of an activity foryou, so you do not need to finish your own activities. Calling thesemethods could adversely affect the expected user experience andshould only be used when you absolutely do not want the user toreturn to this instance of the activity.

注释:大多数情况下,你都不需要显式地使用上面的方法关闭窗口,就像接下来的部分讨论的窗口生命周期那样,Android系统会替你管理窗口的生命,所以你不需要关闭你的窗口。调用这些方法会对用户体验产生不好的影响,除非你是真的不想让用户再返回这个窗口实例了。

Managing theActivity Lifecycle管理窗口的生命周期


Managingthe lifecycle of your activities by implementing callback methods iscrucial to developing a strong and flexible application. Thelifecycle of an activity is directly affected by its association withother activities, its task and back stack.

实现回调方法来管理应用程序的生命周期是开发一个强大且灵活应用的关键。窗口的生命周期也会被与它相关的窗口直接影响,这就是任务和回退栈。

Anactivity can exist in essentially three states:

一个窗口可以存在三种状态:

Resumed--〔中断之后〕继续
Theactivity is in the foreground of the screen and has user focus.(This state is also sometimes referred to as "running".)
窗口在屏幕前台并且获得焦点。(有时也将此状态叫做“运行中”)
Paused---暂停(失去焦点但可见)
Anotheractivity is in the foreground and has focus, but this one is stillvisible. That is, another activity is visible on top of this oneand that activity is partially transparent or doesn't cover theentire screen. A paused activity is completely alive(the Activity objectis retained in memory, it maintains all state and memberinformation, and remains attached to the window manager), but canbe killed by the system in extremely low memory situations.
其他窗口被切换到前台并获得焦点,但是此窗口任然可见。就是说,其他窗口时在此窗口上面可见,但是那个窗口是部分透明的或没有全部覆盖屏幕。一个暂停的窗口是完全“活着”的。也就是说,这个activity对象任然存在于内存中,并且保持着状态和成员信息,并且被窗口管理器管理。当然,如果系统出现内存特别低的情况,这个被暂停的窗口有可能被销毁。
Stopped---停止(失去焦点并不可见)
Theactivity is completely obscured by another activity (the activityis now in the "background"). A stopped activity is alsostill alive (the Activity objectis retained in memory, it maintains all state and memberinformation, but is not attachedto the window manager). However, it is no longer visible to theuser and it can be killed by the system when memory is neededelsewhere.
当前窗口被其他窗口完全屏蔽(当前窗口在后台)。被停止的窗口任然存活(窗口对象任然在内存中,并保持着所有状态和成员信息,但是没有连接窗口管理器)。然后,它不再对用户可见,如果其他程序需要内存,它会被销毁。

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

如果窗口被暂停或停止,系统会通过调用finish()方法将它从内存中删除,或者简单地杀死他的进程。当被关闭或杀死后的窗口重新被打开,所有的东西都会重新创建。

Implementingthe lifecycle callbacks实现生命周期回调方法

Whenan activity transitions into and out of the different statesdescribed above, it is notified through various callback methods. Allof the callback methods are hooks that you can override to doappropriate work when the state of your activity changes. Thefollowing skeleton activity includes each of the fundamentallifecycle methods:

当窗口在上面描述的不同状态间转换时,它是调用了很多回调方法。所有的回调方法你都可以复写,来在你的窗口状态改变时完成恰当的工作。下面的概要窗口类包含了所有重要的生命周期方法。

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: Yourimplementation of these lifecycle methods must always call thesuperclass implementation before doing any work, as shown in theexamples above.

注释:你必须总是在实现生命周期方法时先调用父类实现方法(调用super.xxx()),就像上面的例子那样。

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

  • The entirelifetime ofan activity happens between the call to onCreate() andthe call to onDestroy().Your activity should perform setup of "global" state (suchas defining layout) in onCreate(),and release all remaining resources in onDestroy().For example, if your activity has a thread running in the backgroundto download data from the network, it might create that threadin onCreate() andthen stop the thread inonDestroy().

  • The visiblelifetime ofan activity happens between the call to onStart() andthe call to onStop().During this time, the user can see the activity on-screen andinteract with it. For example, onStop() iscalled when a new activity starts and this one is no longer visible.Between these two methods, you can maintain resources that areneeded to show the activity to the user. For example, you canregister a BroadcastReceiver inonStart() tomonitor changes that impact your UI, and unregister itin onStop() whenthe user can no longer see what you are displaying. The system mightcall onStart() and onStop() multipletimes during the entire lifetime of the activity, as the activityalternates between being visible and hidden to the user.

  • The foregroundlifetime ofan activity happens between the call to onResume() andthe call to onPause().During this time, the activity is in front of all other activitieson screen and has user input focus. An activity can frequentlytransition in and out of the foreground—for example, onPause() iscalled when the device goes to sleep or when a dialog appears.Because this state can transition often, the code in these twomethods should be fairly lightweight in order to avoid slowtransitions that make the user wait.

Figure1 illustrates these loops and the paths an activity might takebetween states. The rectangles represent the callback methods you canimplement to perform operations when the activity transitions betweenstates.

Figure1. Theactivity lifecycle.

Thesame lifecycle callback methods are listed in table 1, whichdescribes each of the callback methods in more detail and locateseach one within the activity's overall lifecycle, including whetherthe system can kill the activity after the callback method completes.

Table1. Asummary of the activity lifecycle's callback methods.

Method

Description

Killableafter?

Next

onCreate()

Calledwhen the activity is first created. This is where you should doall of your normal static set up — create views, bind data tolists, and so on. This method is passed a Bundle objectcontaining the activity's previous state, if that state wascaptured (see SavingActivity State, later).

Alwaysfollowed by onStart().

No

onStart()

    

onRestart()

Calledafter the activity has been stopped, just prior to it beingstarted again.

Alwaysfollowed by onStart()

No

onStart()

onStart()

Calledjust before the activity becomes visible to the user.

Followedby onResume() ifthe activity comes to the foreground, or onStop() ifit becomes hidden.

No

onResume() 
or
onStop()

    

onResume()

Calledjust before the activity starts interacting with the user. Atthis point the activity is at the top of the activity stack, withuser input going to it.

Alwaysfollowed by onPause().

No

onPause()

onPause()

Calledwhen the system is about to start resuming another activity. Thismethod is typically used to commit unsaved changes to persistentdata, stop animations and other things that may be consuming CPU,and so on. It should do whatever it does very quickly, becausethe next activity will not be resumed until it returns.

Followedeither by onResume() ifthe activity returns back to the front, or by onStop() ifit becomes invisible to the user.

Yes

onResume() 
or
onStop()

onStop()

Calledwhen the activity is no longer visible to the user. This mayhappen because it is being destroyed, or because another activity(either an existing one or a new one) has been resumed and iscovering it.

Followedeither by onRestart() ifthe activity is coming back to interact with the user, orbyonDestroy() ifthis activity is going away.

Yes

onRestart()
or
onDestroy()

onDestroy()

Calledbefore the activity is destroyed. This is the final call that theactivity will receive. It could be called either because theactivity is finishing (someone called finish() onit), or because the system is temporarily destroying thisinstance of the activity to save space. You can distinguishbetween these two scenarios with the isFinishing() method.

Yes

nothing

Thecolumn labeled "Killable after?" indicates whether or notthe system can kill the process hosting the activity at anytime afterthe method returns,without executing another line of the activity's code. Three methodsare marked "yes": (onPause()onStop(),and onDestroy()).Because onPause() isthe first of the three, once the activity is created, onPause() isthe last method that's guaranteed to be called before theprocess canbekilled—if the system must recover memory in an emergency,then onStop() and onDestroy() mightnot be called. Therefore, you should use onPause() towrite crucial persistent data (such as user edits) to storage.However, you should be selective about what information must beretained during onPause(),because any blocking procedures in this method block the transitionto the next activity and slow the user experience.

Methodsthat are marked "No" in the Killable columnprotect the process hosting the activity from being killed from themoment they are called. Thus, an activity is killable from thetime onPause() returnsto the timeonResume() iscalled. It will not again be killable until onPause() isagain called and returns.

Note: Anactivity that's not technically "killable" by thisdefinition in table 1 might still be killed by the system—but thatwould happen only in extreme circumstances when there is no otherrecourse. When an activity might be killed is discussed more inthe Processesand Threading document.

Savingactivity state

Theintroduction to Managingthe Activity Lifecycle brieflymentions that when an activity is paused or stopped, the state of theactivity is retained. This is true because the Activity objectis still held in memory when it is paused or stopped—allinformation about its members and current state is still alive. Thus,any changes the user made within the activity are retained so thatwhen the activity returns to the foreground (when it "resumes"),those changes are still there.

However,when the system destroys an activity in order to recover memory,the Activity objectis destroyed, so the system cannot simply resume it with its stateintact. Instead, the system must recreate the Activity objectif the user navigates back to it. Yet, the user is unaware that thesystem destroyed the activity and recreated it and, thus, probablyexpects the activity to be exactly as it was. In this situation, youcan ensure that important information about the activity state ispreserved by implementing an additional callback method that allowsyou to save information about the state of youractivity: onSaveInstanceState().

Thesystem calls onSaveInstanceState() beforemaking the activity vulnerable to destruction. The system passes thismethod a Bundle inwhich you can save state information about the activity as name-valuepairs, using methods such as putString() and putInt().Then, if the system kills your application process and the usernavigates back to your activity, the system recreates the activityand passes the Bundle toboth onCreate() andonRestoreInstanceState().Using either of these methods, you can extract your saved state fromthe Bundle andrestore the activity state. If there is no state information torestore, then the Bundle passedto you is null (which is the case when the activity is created forthe first time).



Figure2. Thetwo ways in which an activity returns to user focus with its stateintact: either the activity is destroyed, then recreated and theactivity must restore the previously saved state, or the activity isstopped, then resumed and the activity state remains intact.

Note: There'sno guarantee that onSaveInstanceState() willbe called before your activity is destroyed, because there are casesin which it won't be necessary to save the state (such as when theuser leaves your activity using the Back button,because the user is explicitly closing the activity). If the systemcallsonSaveInstanceState(),it does so before onStop() andpossibly before onPause().

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

Youcan also explicitly stop a view in your layout from saving its stateby setting the android:saveEnabledattributeto "false" orby calling thesetSaveEnabled() method.Usually, you should not disable this, but you might if you want torestore the state of the activity UI differently.

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

Becausethe default implementation of onSaveInstanceState()helpssave the state of the UI, if you override the method in order to saveadditional state information, you should always call the superclassimplementation ofonSaveInstanceState() beforedoing any work. Likewise, you should also call the superclassimplementation ofonRestoreInstanceState() ifyou override it, so the default implementation can restore viewstates.

Note: Because onSaveInstanceState() isnot guaranteed to be called, you should use it only to record thetransient state of the activity (the state of the UI)—you shouldnever use it to store persistent data. Instead, you shoulduse onPause() tostore persistent data (such as data that should be saved to adatabase) when the user leaves the activity.

Agood way to test your application's ability to restore its state isto simply rotate the device so that the screen orientation changes.When the screen orientation changes, the system destroys andrecreates the activity in order to apply alternative resources thatmight be available for the new screen configuration. For this reasonalone, it's very important that your activity completely restores itsstate when it is recreated, because users regularly rotate the screenwhile using applications.



时间:

2014-11-3星期一16:01:42

翻译原因:

好好的免费而强大的学习资源硬生生被和谐,害的我们要去看各种完整的不完整的乱七八糟的文档,甚至去上培训班。那么有机会得到这些原文档,就拿出来跟大家分析。翻译只是对自己理解的情况的一种展现,方便大家学习也让自己进步。所以,共同努力!

当然,鉴于个人水平有限,有错误或翻译不当的地方请大家指正,也欢迎大家一起来做这件事。

感谢:

安卓官网文档:http://developer.android.com/guide/components/activities.html

百度翻译:http://fanyi.baidu.com

海词在线翻译:http://fanyi.dict.cn

GoldenDictwww.goldendict.org

LibreOfficehttp://zh-cn.libreoffice.org/

作者:tops

163博客:http://huolangge.blog.163.com/

csdn博客:http://blog.csdn.net/topsyfc


0 0
原创粉丝点击