Activities

来源:互联网 发布:萧井陌 编程入门指南 编辑:程序博客网 时间:2024/05/22 04:38

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.

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" stack mechanism, so, when the user is done with the current activity and presses the Back button, 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.)

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.

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.

Creating an 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:

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

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.

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.

Android provides a number of ready-made views that you can use to design and organize your layout. "Widgets" are views that provide 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 ViewGroupclasses (or existing subclasses) to create your own widgets and layouts and apply them to your activity layout.

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 tosetContentView().

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

Declaring the activity in the manifest

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

<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. The android:name attribute is the only required attribute—it specifies the class name of the activity. Once you publish your application, you should not change this name, because if you do, you might break some functionality, such as application shortcuts (read the blog post, Things That Cannot Change).

See the <activity> element reference for more information about declaring your activity in the manifest.

Using intent filters

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.

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:

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

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

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.

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

Starting an 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.

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:

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:

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.

Starting an activity for a result

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 your onActivityResult() method.

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:

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

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 resultCodewill be RESULT_OK—and whether the request to which this result is responding is known—in this case, therequestCode matches the second parameter sent with startActivityForResult(). From there, the code handles the activity result by querying the data returned in an Intent (the data parameter).

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.

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

Shutting Down an 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().

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.

Managing the Activity Lifecycle


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.

An activity can exist in essentially three states:

Resumed
The activity is in the foreground of the screen and has user focus. (This state is also sometimes referred to as "running".)
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.
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.

If an activity is paused or stopped, the system can drop it from memory either 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.

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:

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.

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:

  • 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) in onCreate(), 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 inonDestroy().
  • 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 inonStart() 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.

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

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.

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

MethodDescriptionKillable after?NextonCreate()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().

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

Always followed by onStart()

NoonStart()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.

NoonResume() 
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().

NoonPause()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.

YesonResume() 
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.

YesonRestart()
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.Yesnothing

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.

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 time onPause() returns to the timeonResume() is called. It will not again be killable until onPause() is again called and returns.

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.

Saving activity state

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 so that when 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 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: onSaveInstanceState().

The system calls onSaveInstanceState() before making the activity vulnerable to destruction. The system passes this method a Bundle in which you can save state information about the activity as name-value pairs, using methods such as putString() and putInt(). Then, if the system kills your application process and the user navigates back to your activity, the system recreates the activity and passes the Bundle to bothonCreate() and onRestoreInstanceState(). Using either of these methods, you can extract your saved state from the Bundle and restore the activity state. If there is no state information to restore, then the Bundlepassed to you is null (which is the case when the activity is created for the first time).

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

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 button, because the user is explicitly closing the activity). If the system callsonSaveInstanceState(), it does so before onStop() and possibly before 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 the corresponding onSaveInstanceState() method 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 of 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 the system cannot save its state.

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

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. Likewise, you should also call the superclass implementation of onRestoreInstanceState() if you override it, so the default implementation can restore view states.

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.

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 screen configuration. 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.

Handling configuration changes

Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android recreates the running activity (the system calls onDestroy(), then immediately calls onCreate()). This behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that you've provided (such as different layouts for different screen orientations and sizes).

If you properly design your activity to handle a restart due to a screen orientation change and restore the activity state as described above, your application will be more resilient to other unexpected events in the activity lifecycle.

The best way to handle such a restart is to save and restore the state of your activity usingonSaveInstanceState() and onRestoreInstanceState() (or onCreate()), as discussed in the previous section.

For more information about configuration changes that happen at runtime and how you can handle them, read the guide to Handling Runtime Changes.

Coordinating activities

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.

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:

  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.

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().

一个活动是一个应用程序组件,它提供了用户可以为了做一些事情,如拨打电话,拍照,发送电子邮件,或查看地图进行交互的屏幕。每个活动都有一个窗口,在其中绘制它的用户界面。窗口典型地充满屏幕,也可以是小于屏幕和浮在其它窗口之上。

一个应用程序通常由被松散地结合到彼此的多个活动。通常情况下,在应用程序中一个活动被指定为“主”的活性,这是启动首次应用时呈现给用户。然后,每个活动可以以执行不同的操作启动另一个活动。每一个新的活动开始时间,先前的活动停止了,但该系统保持在一个叠层(“回堆叠”)的活性。当一个新的活动启动时,它被压入堆栈回来,并采取用户关注的焦点。后退堆栈遵守基本的“后进先出”的堆栈机制,这样,当用户与当前活动的完成,按下后退按钮,它从栈中弹出(和销毁)和以前的活动恢复。(背面堆栈多在讨论任务和返回堆栈文件。)

当活动停止,因为一个新的活动启动时,它被通知通过活动的生命周期回调方法这种变化的状态。有几种回调方法的活动可能会收到,由于其改变状态系统是否创造它,阻止它,恢复它,或者毁坏它和每个回调为您提供执行是合适的具体工作机会该状态更改。例如,停止时,你的活动应当释放任何大的物体,如网络或数据库连接。当活动恢复,则可以重新获取必要的资源,并恢复被中断的行动。这些状态转换是活动的生命周期的所有部分。

本文档的其余部分将讨论如何建立和使用活动,包括活动的生命周期是如何工作的完整讨论的基础知识,这样你就可以妥善管理各种活动状态之间的转换。

创建活动


要创建活动,必须创建一个子类活动(或它的一个子类存在的)。在子类中,你需要实现回调方法,该系统调用时,正在创建活动时,如生命周期,不同状态之间的转换活动,停止,重新开始,或销毁。两个最重要的回调方法是:

的onCreate()
您必须实现此方法。创建活动时,系统调用此。在您的实现,你应该初始化活动的重要组成部分。最重要的是,这是你必须调用的setContentView()来定义该活动的用户界面的布局。
的onPause()
系统调用此方法,因为该用户离开你的活动(尽管它并不总是意味着该活动被销毁)的第一个迹象。这通常是你应该犯应当超越当前用户会话被持久化(因为用户可能不会回来)的任何变化。

还有,你应该以提供活动之间的流体用户体验和处理突发interuptions导致您的活动必须停止,甚至销毁使用其他几个生命周期回调方法。所有的生命周期回调方法将在稍后讨论,在对部分管理活动的生命周期。

实现用户接口

对于活动的用户界面是由从所导出的观点-对象的层次提供视图类。每个视图控制活动的窗口内的特定的矩形空间,并且可以响应用户交互。例如,一个视图可以是一个按钮,当用户触摸它发起一个动作。

Android提供了多种方法,您可以用它来 ​​设计和组织布局现成的看法。“部件”是次提供用于在屏幕视觉(和交互)元素,诸如按钮,文本字段,复选框,或者仅仅一个图像。“布局”是源于意见的ViewGroup如线性布局,网格布局,或相对布局提供其子视图,独特的布局模式。你也可以继承的视图和 一个ViewGroup类(或现有的子类)来创建自己的部件和布局,并将它们应用到你的活动布局。

定义使用视图布局最常用的方法是保存在您的应用程序资源的XML布局文件。通过这种方式,可以从定义活动行为的源代码分开维护你的用户界面的设计。您可以设置布局的UI您有活动的setContentView)( ,传递的资源ID布局。但是,您也可以创建新的查看你的活动代码S和建立由插入新视图层次视图 s转换为ViewGroup中,然后通过将根使用该布局 的ViewGroup的setContentView() 

有关创建用户界面的信息,请参阅用户界面文档。

声明的活动清单

您必须声明清单文件中的活动,以便它是对系统进行访问。要声明你的活动,打开你的manifest文件并添加<活动>元素作为一个孩子<应用程序> 元素。例如:

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

还有一些其他的属性,这些属性可以对这个元素来定义,如标签的活动,为活动的图标,或者一个主题样式活动的UI特性。该机器人:名称 属性是唯一必需的属性,它指定活动的类名。一旦你发布你的应用程序时,你不应该改变这个名字,因为如果你这样做,你可能会打破一些功能,如应用程序快捷方式(阅读博客文章,事情可以不更改)。

请参阅<活动>关于在清单中声明你的活动的更多信息元素引用。

使用意图过滤器

一个<活动>元素也可以指定不同的意图过滤器,使用<意图过滤器>的元素以如何申报其他应用程序组件可以激活它。

当您创建使用Android SDK工具新的应用程序,这是为您创建存根活动自动包括声明该活动的意图过滤器响应“主”的行动,应放在“启动”的范畴。这样做的目的过滤器看起来是这样的:

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

<操作>元素指定这是“主”入口点的应用程序。在<category>中元素指定这一活动应在系统中的应用程序启动上市(允许用户推出这项活动)。

如果您打算让您的应用程序是自包含的,而不是允许其他应用程序来激活它的活动,那么你不需要任何其他的意图过滤器。只有一个活动应该有“主”行动和“发射”的范畴,如前面的示例所示。你不想提供给其他应用程序的活动应该没有意图过滤器,您可以使用显式意图自己启动它们(如在下一节讨论)。

不过,如果你希望你的活动,以响应从其他应用程序(和你自己)提供隐含的意图,那么你必须为你的活动定义额外的意图过滤器。对于每种类型要回应的意图,你必须包括<意图过滤器>,其中包括一个 <动作>元素和可选,一个<category>中元素和/或<数据>元素。这些元素指定意图,你的活动可以响应的类型。

有关你的活动如何为响应意图的更多信息,请参阅意图和意图过滤器 的文件。

启动一个活动


你可以通过调用启动另一个活动startActivity() ,传递一个意图描述您要启动的活动。这样做的目的不是指定要启动的具体活动或描述要执行的操作类型(和系统为您选择合适的活动,甚至可以从不同的应用程序)。意图还可以携带少量的数据由该开始的活动中使用。

当自己的应用程序中工作,你会经常需要简单地启动一个已知的活动。您可以通过创建一个明确定义要启动该活动,使用类名的意图这样做。例如,这里有一个活动是如何启动另一个名为活动SignInActivity

意向意图=   意图 SignInActivity ); startActivity 意向);

然而,你的应用程序也可能需要执行一些动作,如发送电子邮件,短信或状态更新,使用从你的活动数据。在这种情况下,您的应用程序可能没有自己的活动来执行这样的动作,这样你就可以利用,而不是由设备上的其他应用程序,它可以为您执行的操作提供的活动。这是意图是真正有价值的,你可以创建一个描述要执行的操作,系统从另一个应用程序启动相应的活动的意图。如果有,可以处理的意图多个活动,则用户可以选择使用哪一个。例如,如果你想允许用户发送电子邮件,您可以创建以下目的:

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

EXTRA_EMAIL额外添加到意图是该电子邮件应该发送电子邮件地址的字符串数组。当电子邮件应用程序响应这个意图,它读取额外提供的字符串数组,并把它们在电子邮件撰写表格的“到”字段中。在这种情况下,电子邮件应用程序的活动开始,并在用户完成时,你的活动恢复。

启动一个活动结果

有时候,你可能需要从你开始活动收到结果。在这种情况下,启动通过调用活动startActivityForResult()(代替startActivity() )。要再从后续活动得到的结果,实现的onActivityResult()回调方法。当随后的活动完成时,它在一个返回结果意图到您的onActivityResult() 方法。

例如,也许你希望用户来接他们的联系人之一,因此你的活动可以做一些与该联系人的信息。这里是你如何能创建这样的意图和处理的结果:

私人 无效pickContact () {     //创建一个意图,“挑”的联系人,由内容提供商定义                如果申请顺利(OK),并请求是PICK_CONTACT_REQUEST     如果 resultCode为==  活动RESULT_OK && requestCode == PICK_CONTACT_REQUEST  {         //执行一个查询联系人的内容提供商联系人                                 如果光标不                                     做选择的联系人的姓名东西... ...         }     } }

这个例子显示,你应该在你使用的基本逻辑的onActivityResult()方法以处理活动的结果。第一个条件检查该请求是否成功-如果是,则发送resultCodeRESULT_OK -and请求到这一结果是响应是已知的,在这种情况下,是否requestCode与发送的第二参数相匹配()startActivityForResult。从那里,将码处理通过查询在一个返回数据的活动结果意图(该数据参数)。

什么情况是,一个ContentResolver的执行对内容提供商,它返回的查询 光标,允许读取查询数据。欲了解更多信息,请参阅内容提供商的文档。

有关使用意图的更多信息,请参阅意图和意图过滤器的文件。

关闭一个活动


你可以通过调用其关闭活动结束()方法。您也可以关闭您以前通过调用启动一个单独的活动finishActivity() 

注:在大多数情况下,你应该没有明确结束使用这些方法的活动。如同在活动周期下一节讨论的,Android系统为您管理活动的生活,所以你不需要来完成自己的活动。调用这些方法可以在预期的用户体验产生不利影响,应仅用于当你绝对不希望用户返回到活动的此实例。

管理活动的生命周期


通过实施回调方法管理你的活动的生命周期是发展强大和灵活的应用至关重要。活动的生命周期直接影响到它与其他的活动,它的任务和回堆栈关联。

活性可以在基本上三种状态存在:

恢复
活性是在屏幕的前景中,并具有用户集中。(该状态也有时被称为“运行”)。
已暂停
另一项活动是在前台和具有焦点,但是这一次仍是可见的。即,另一个活动是在这一个的顶部可见和活动是部分透明或不覆盖整个屏幕。一个暂停的activity是完全活着(该活动 对象保留在内存中,它保持所有的状态和成员信息,并保持连接到窗口管理器),但可以通过该系统在非常低内存情况下被杀死。
已停止
活动完全是由另一活动遮蔽(即现在的活动是在“背景”)。停止的活动也仍然活着(该活动 对象保留在内存中,它保持所有的状态和成员信息,但 附加到窗口管理器)。然而,它不再对用户可见,它可以由系统时别处需要存储器被杀死。

如果活动被暂停或停止,该系统可以通过要求它结束(调用它从内存中删除它完成()方法),或者干脆杀死它的进程。当活动再次打开(被完成或死亡后),它必须创建全部结束。

实施生命周期回调

当一个活动的转换进入和离开的不同状态的以上描述,但是通过各种回调方法通知。所有的回调方法是可以重写做适当的工作,当你的活动状态变化挂钩。下面的骨骼活动包括每个基本生命周期方法:

public  class  ExampleActivity  extends  Activity  {     @Override     public  void  onCreate ( Bundle savedInstanceState )  {         super . onCreate ( savedInstanceState );         //正在创建活动。    }     @覆盖    保护 无效 在onStart ()  {         在onStart ();         //活动即将成为可见    }     @覆盖    保护 无效 onResume ()  {         onResume ();         //活动已成为可见(它现在“恢复”)。    }     @覆盖    保护 无效 的onPause ()  {         的onPause ();         //另一项活动正在对焦(这个活动是即将被“暂停”)。    }     @覆盖    保护 无效 的onStop ()  {         的onStop ();         //活动将不再可见(它现在“已停止”)    }     @覆盖    保护 无效 的onDestroy ()  {         的onDestroy ();         //活动是即将被销毁。    } }

注意:您执行这些生命周期方法必须始终调用父类的实现做任何工作之前,如上面的例子中。

两者合计,这些方法定义了一个活动的整个生命周期。通过实施这些方法,你可以监视活动的生命周期三个嵌套循环:

  • 整个生命周期的活动发生在调用之间的onCreate()和调用的onDestroy() 。您的活动应该执行的“全球性”的状态设置(如定义布局)的onCreate() ,并释放所有剩余资源的onDestroy() 。例如,如果你的活动在后台从网络下载数据运行一个线程,这也许可以在该线程的onCreate() ,然后停止线程的onDestroy() 
  • 可视生命周期的活动发生在调用之间在onStart()和调用的onStop() 。在此期间,用户可在屏幕上看到的活性和与它进行交互。例如,的onStop()当一个新的活动开始和这一个不再可见被调用。这两种方法之间,可以保持所需要以显示活动给用户的资源。例如,您可以注册一个 广播接收器调用onStart()来监视影响您的用户界面的变化,并注销它的onStop()当用户不再能看到你什么显示。系统可能会调用调用onStart()的onStop()的活动的整个寿命期间多次,作为是可见和隐藏到用户之间的活动交替。

  • 前台一生的活动发生在调用之间onResume()和调用的onPause() 。在此期间,该活动是在屏幕上的所有其他活动的前面,并具有用户输入的焦点。一个活动可以频繁转换进出前景,例如,在onPause()被调用时,该设备进入睡眠状态或将出现一个对话框时。因为该状态通常可以转换,在这两种方法中的代码应以避免慢过渡,使用户的等待相当轻巧。

图1说明了这些环和一个活动可能采取状态之间的路径。矩形代表可以实现在活动状态之间的转换来执行操作的回调方法。

图1的活动的生命周期。

同样的生命周期回调方法列于表1,其中描述了各自的回调方法的细节,并找到活动的整体生命周期中的每个人,包括回调方法完成后系统是否能杀死活动。

表1的活性生命周期的回调方法的摘要。

方法描述Killable后?下一个的onCreate()第一次创建活动时调用。这是你应该做的所有的正常静态设置的-创建视图,数据绑定到列表,等等。这种方法是通过包含活动的以前的状态一个Bundle对象,如果那个状态被抓获(见保存活动状态,更高版本)。

总是跟随在onStart() 

没有在onStart() onRestart()后调用该活动已停止,只是在它之前被再次启动。

总是跟随在onStart()

没有在onStart()在onStart()叫之前的活性变得对用户可见。

其次是onResume()如果活动来到前台,或的onStop() 如果它被隐藏。

没有onResume() 
的onStop()
 onResume()叫之前的活动开始与用户交互。在这一点上的活动是在活动堆栈的顶部,与用户输入要它。

总是跟着的onPause() 

没有的onPause()的onPause()当调用系统即将启动恢复另一个活动。此方法通常用于提交到持久性数据未保存的更改,停止动画和可消耗CPU等其他东西。它应该尽一切可能很快确实,因为接下来的活动将不会被恢复,直到它返回。

接着或者通过onResume()如果活动返回到前面,或通过的onStop()如果它变得对用户不可见。

onResume() 
的onStop()
的onStop()当活动不再对用户可见调用。这种情况可能发生,因为它被销毁,或者是因为其他活动(无论是现有的或新的)已经恢复并且覆盖它。

其次无论是onRestart()如果活动是回来与用户交互,或通过 的onDestroy()如果此活动消失。

onRestart()
的onDestroy()
的onDestroy()该活动被破坏之前调用。这是该活动将获得最后的通话。它可以被称为是因为活性被整理(有人称为光洁度()在其上),或者是因为该系统暂时破坏活性的此实例以节省空间。你可以这两个方案的区别isFinishing()方法。没有

列标有“后Killable?” 指示系统是否能杀死宿主随时活性的过程在方法返回之后,不执行活动的代码的另一行。三种方法被标记为“是”:(的onPause() 的onStop() ,和的onDestroy() )。因为的onPause()是第三,一旦被创建的活性,的onPause()是有保证被调用的过程之前的最后一个方法可以被杀死,如果系统必须在紧急恢复存储器,然后的onStop()的onDestroy()可能不被调用。因此,你应该使用的onPause()写关键的持久性数据(如用户编辑)到存储。然而,你应该是有选择性的关于什么样的信息必须在被保留的onPause() ,因为这种方法阻止任何封锁程序过渡到下一个活动并降低用户体验。

被标记方法“否”,在Killable柱保护托管从它们被称为瞬间被杀死活性的过程。因此,一个活动是killable从时间的onPause()返回到时间 onResume()被调用。它不会再次killable到 的onPause()再次调用并返回。

注意:这不是技术上“killable”通过这个定义在表1所述的活动可能仍然被杀死的系统,但在没有其他办法,将只发生在极端的情况下。当可能被杀死的活动中讨论更多的进程和线程的文件。

节能活动状态

引入到管理活动的生命周期短暂地提到,当活动被暂停或停止,该活动的状态被保留。因为这是真实的活动目标仍然是在内存或持有时暂停停所有关于其成员和当前状态的信息仍然活着。因此,在活动范围内所做的任何修改,用户被保留,这样,当活动返回到前景(当它“恢复”)时,这些更改仍然存在。

然而,当系统破坏以回收存储器的活性,该活性对象被破坏,所以其状态不变系统不能简单地恢复它。相反,系统必须重新创建活动,如果用户导航回 ​​到它的对象。然而,用户不知道该系统破坏了活性和重新创建它,并且因此,可能是期望的活性是完全原样。在这种情况下,可以确保通过实施额外的回调方法,可以让您保存您的活动状态的信息保留有关的活动状态的重要信息:的onSaveInstanceState() 

该系统调用的onSaveInstanceState() 使活动容易受到破坏之前。该系统通过这个方法捆绑在其中可以节省约活动的名称-值对的状态信息,使用方法,如putString()putInt() 。然后,如果系统杀死你的应用程序和用户导航回 ​​到您活动,该系统重新创建活动,并传递捆绑两者的onCreate()onRestoreInstanceState() 。使用这两种方法,您可以从中提取您的保存状态和恢复活动状态。如果没有状态信息来恢复,则传递给你为空(这是当在第一次创建活动的情况下)。

图2.两种方式,其中一项活动返回给用户关注的焦点,其状态完好:要么活性被破坏,然后重新创建活动必须恢复以前保存的状态,或活动停止,然后重新开始,活动状态保持完整。

注意:有没有保证的onSaveInstanceState()您的活动被销毁之前会被调用,因为在它没有必要保存状态(当用户离开使用您的活动,如情况下后退按钮,因为用户被显式关闭活动)。如果系统调用的onSaveInstanceState() ,它这样做之前的onStop()和可能之前的onPause() 

但是,即使你什么也不做,没有实现的onSaveInstanceState() ,一些活动状态是由恢复活动类的默认实现的onSaveInstanceState() 。具体来说,默认实现调用相应的onSaveInstanceState()为每个方法查看布局,它允许每个视图提供其自身应保存的信息。几乎是在Android框架部件的每实现此方法,适当的,这样的UI任何可见的更改会自动保存,当你的活动重新恢复。例如,的EditText部件保存用户输入的任何文字和复选框控件节省不管是检查还是不行。你唯一需要的工作是提供一个唯一的ID(与机器人:ID 属性)为要保存其状态每个插件。如果一个部件没有一个ID,则系统无法保存其状态。

虽然默认实现的onSaveInstanceState()保存有关你的活动的UI有用的信息,你可能仍然需要重写,以节省更多的信息。例如,您可能需要保存活动的生命过程中更改成员值(这可能关联到UI中恢复的价值,但持有这些UI值的成员不会被恢复,默认情况下)。

因为默认实现的onSaveInstanceState()有助于保存UI的状态,如果你覆盖的方法,以节省额外的状态信息,你应该总是调用父类实现)的onSaveInstanceState( 做任何工作之前。同样的,你也应该调用父类实现onRestoreInstanceState() ,如果你忽略它,所以默认的实现可以恢复视图状态。

注:由于的onSaveInstanceState()不能保证被调用,你应该只用它来 ​​记录活动(用户界面)的状态-你永远不应该用它来 ​​存储持久性数据的临时状态。相反,你应该使用 的onPause()来存储持久性数据(如应保存到数据库中的数据),当用户离开该活动。

测试你的应用程序,以恢复其状态的能力的一个好方法是简单地旋转装置,使屏幕的方向变化。当屏幕方向改变时,系统会破坏并重新创建,以便应用替代资源,可能是可用于新的屏幕配置的活动。仅仅出于这个原因,这是非常重要的,你的活动完全恢复其状态,当它被重建,因为用户在使用应用程序定期旋转屏幕。

处理配置更改

有些设备配置可以在运行时改变(如屏幕方向,键盘可用性,和语言)。当这种变化发生时,Android的再现了运行的活动(系统调用的onDestroy() ,然后立即调用的onCreate() )。此行为旨在帮助您的应用程序自动重新加载与您所提供(如不同的屏幕方向和大小不同的布局)的替代资源,您的应用程序适应新的配置。

如果你正确地设计您的活动来处理重新启动由于屏幕方向变化和恢复上述的活动状态,应用程序将更加适应在活动周期等突发事件。

处理这样一个重启的最好方法是保存和恢复您的活动使用状态的onSaveInstanceState()onRestoreInstanceState() (或的onCreate() ),在上一节中讨论。

有关发生在运行时,你如何处理它们的配置更改的更多信息,请阅读指导,以处理运行时更改。

活动协调

当一个活动启动另一个,他们都经历了生命周期的转变。第一项活动暂停和停止(不过,如果它仍然在后台可见它不会停止),而创建其他活动。如果这些活动分享保存在光盘上的数据或其他地方,了解所创建的第二个之前的第一个活动是没有完全停止是很重要的。相反,开始第二个的方法与停止第一一个的过程重叠。

生命周期回调的顺序被很好地定义,特别是当这两种活动都在同一个过程,一个在开始其他。这里的操作时,活动A开始Acivity乙发生的顺序:

  1. 活动A的的onPause()方法执行。
  2. 活动B的的onCreate() 在onStart()onResume() 方法执行顺序。(活动B现在用户关注的焦点。)
  3. 然后,如果活动A在屏幕上不再可见,它的onStop()方法执行。

这种可预见的生命周期回调的顺序可以让你从一个活动到另一个管理信息的转变。例如,如果在第一个活动停止,这样下面的活动可以读取它必须写入到数据库中,那么你应该在写入数据库的onPause() ,而不是过程中的onStop() 


1 0