Activity生命周期

The Activity Lifecycle

Activity生命周期

As a user navigates through, out of, and back to your app, the Activity instances in your app transition through different states in their lifecycle. The Activity class provides a number of callbacks that allow the activity to know that a state has changed: that the system is creating, stopping, or resuming an activity, or destroying the process in which the activity resides.

作为一个用户导航通过退出,返回的app,Activity实例在app中通过它的生命周期转变(不同的)状态。Activity提供了一系列 回调函数去允许Activity知道(它的)状态变化:系统正在创建、停止或者恢复Activity,或者销毁Activity驻留的进程。

Within the lifecycle callback methods, you can declare how your activity behaves when the user leaves and re-enters the activity. For example, if you're building a streaming video player, you might pause the video and terminate the network connection when the user switches to another app. When the user returns, you can reconnect to the network and allow the user to resume the video from the same spot. In other words, each callback allows you to perform specific work that's appropriate to a given change of state. Doing the right work at the right time and handling transitions properly make your app more robust and performant. For example, good implementation of the lifecycle callbacks can help ensure that your app avoids:

在生命周期回调方法中,当用户离开和重新进入Activity的时候你可以声明Activity的(不同)行为。例如,如果你构建了一个流媒体视频播放器,当用户切换到其他app的时候你可能会暂停视频并且终止网络连接。当用户返回时,你可以重连网络并且允许用户从同一点恢复视频。换句话说,每个回调允许执行特定于给定适当的状态变化的特定工作。控制状态在正确的时间做正确的工作会让app更加稳定和高效。例如,良好的实现生命周期的回调函数能帮助你确保app避免以下几点:

  • Crashing if the user receives a phone call or switches to another app while using your app.
  • 在使用你的app时,如果用户接电话或者切换到另一个app时你的app崩溃。
  • Consuming valuable system resources when the user is not actively using it.
  • 当用户不常使用它是消耗有价值的系统资源。
  • Losing the user's progress if they leave your app and return to it at a later time.
  • 如果用户离开app并且之后返回时丢失用户进度。
  • Crashing or losing the user's progress when the screen rotates between landscape and portrait orientation.
  • 当(app)切换横竖屏时崩溃或者丢失用户进度。

This document explains the activity lifecycle in detail. The document begins by describing the lifecycle paradigm. Next, it explains each of the callbacks: what happens internally while they execute, and what you should implement during them. It then briefly introduces the relationship between activity state and a process’s vulnerability to being killed by the system. Last, it discusses several topics related to transitions between activity states.

本文档详细的讲解了Activity的生命周期。本文档首先描述生命周期范式。接着讲解每一个回调:它们执行时内部发生了什么,以及在它们执行时你应该实现什么。然后简要介绍了Activity状态与系统被系统杀死的脆弱性之间的关系。最后,讨论了与Activity状态转换相关的几个主题。

For information about handling lifecycles, including guidance about best practices, see Handling Lifecycles.

更多的有关处理生命周期的信息,包括最佳练习指导,请参见Handling Lifecycles

Activity-lifecycle concepts

Activity生命周期概念

To navigate transitions between stages of the activity lifecycle, the Activity class provides a core set of six callbacks: onCreate()onStart(),onResume()onPause()onStop(), and onDestroy(). The system invokes each of these callbacks as an activity enters a new state.

为了指导Activity生命周期各阶段之间的转换,Activity提供了六个核心的回调函数:onCreate()onStart(),onResume()onPause()onStop(), 和 onDestroy()。当Activity进入新状态的时候系统会回调他们。

Figure 1 presents a visual representation of this paradigm.

图1给出了这个范例的可视化表示。


Figure 1. A simplified illustration of the activity lifecycle.

图1。Activity生命周期的简化说明。

As the user begins to leave the activity, the system calls methods to dismantle the activity. In some cases, this dismantlement is only partial; the activity still resides in memory (such as when the user switches to another app), and can still come back to the foreground. If the user returns to that activity, the activity resumes from where the user left off. The system’s likelihood of killing a given process—along with the activities in it—depends on the state of the activity at the time. Activity state and ejection from memory provides more information on the relationship between state and vulnerability to ejection.

当用户开始离开Activity时,系统会调用方法来移除Activity。在某些情况下,移除仅仅是局部的;Activity仍然驻留在内存中(例如当用户切换到其他app时),并且仍然可以回到前台。如果用户返回到(那个)Activity,Activity会从用户离开的地方恢复。系统杀死一个给定进程的可能性和它在该过程中的Activity取决于Activity当时的状态。Activity state and ejection from memory 提供了更多的有关状态和释放(内存)的脆弱性的信息。

Depending on the complexity of your activity, you probably don't need to implement all the lifecycle methods. However, it's important that you understand each one and implement those that ensure your app behaves the way users expect.

根据Activity的复杂性,你可能不需要实现所有的回调方法。然而,你对每一个回调方法的理解和实现能确保app的行为达到用户的期望是非常重要的。

The next section of this document provides detail on the callbacks that you use to handle transitions between states.

本文档的下一部分提供了用来处理状态转换的回调函数的详细描述。

Lifecycle callbacks

生命周期回调函数


This section provides conceptual and implementation information about the callback methods used during the activity lifecycle.

这部分内容提供了在Activity生命周期中回调方法的概念与实现信息。

onCreate()

You must implement this callback, which fires when the system first creates the activity. On activity creation, the activity enters the  Created  state. In the  onCreate()  method, you perform basic application startup logic that should happen only once for the entire life of the activity. For example, your implementation of  onCreate()  might bind data to lists, initialize background threads, and instantiate some class-scope variables. This method receives the parameter  savedInstanceState , which is a  Bundle  object containing the activity's previously saved state. If the activity has never existed before, the value of the  Bundle  object is null.

你必须实现这个回调函数,它是系统创建Activity时第一个触发的函数。在Activity创建时,Activity进入创建状态。在onCreate()方法中,你应该执行在Activity整个生命周期中只执行一次的基本的应用程序启动逻辑。例如,在onCreate()方法中你可能将数据绑定到列表,初始化后台线程,以及初始化一些全局变量。该函数接收savedInstanceState参数,它(savedInstanceState)是一个包含Activity之前保存状态的Bundle对象。如果Activity之前没有存在,Bundle对象的值为空。

The following example of the onCreate() method shows fundamental setup for the activity, such as declaring the user interface (defined in an XML layout file), defining member variables, and configuring some of the UI. In this example, the XML layout file is specified by passing file’s resource ID R.layout.main_activity to setContentView().

下面的例子展示了onCreate()方法的基本设置,例如声明用户界面(在XML文件中定义布局文件),定义成员变量,以及配置一些UI布局。

在这个例子中,XML布局文件通过文件资源IDR.layout.main_activity被指定给setContentView()方法。

KOTLIN

lateinit var textView: TextView

// some transient state for the activity instance
var gameState: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
    // call the super class onCreate to complete the creation of activity like
    // the view hierarchy
    super.onCreate(savedInstanceState)

    // recovering the instance state
    gameState = savedInstanceState?.getString(GAME_STATE_KEY)

    // set the user interface layout for this activity
    // the layout file is defined in the project res/layout/main_activity.xml file
    setContentView(R.layout.activity_main)

    // initialize member TextView so we can manipulate it later
    textView = findViewById(R.id.text_view)
}

// This callback is called only when there is a saved instance that is previously saved by using
// onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore
// other state here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}

// invoked when the activity may be temporarily destroyed, save the instance state here
override fun onSaveInstanceState(outState: Bundle?) {
    outState?.run {
        putString(GAME_STATE_KEY, gameState)
        putString(TEXT_VIEW_KEY, textView.text.toString())
    }
    // call superclass to save any view hierarchy
    super.onSaveInstanceState(outState)
}

JAVA

TextView mTextView;

// some transient state for the activity instance
String mGameState;

@Override
public void onCreate(Bundle savedInstanceState) {
    // call the super class onCreate to complete the creation of activity like
    // the view hierarchy
    super.onCreate(savedInstanceState);

    // recovering the instance state
    if (savedInstanceState != null) {
        mGameState = savedInstanceState.getString(GAME_STATE_KEY);
    }

    // set the user interface layout for this activity
    // the layout file is defined in the project res/layout/main_activity.xml file
    setContentView(R.layout.main_activity);

    // initialize member TextView so we can manipulate it later
    mTextView = (TextView) findViewById(R.id.text_view);
}

// This callback is called only when there is a saved instance that is previously saved by using
// onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore
// other state here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    mTextView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}

// invoked when the activity may be temporarily destroyed, save the instance state here
@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putString(GAME_STATE_KEY, mGameState);
    outState.putString(TEXT_VIEW_KEY, mTextView.getText());

    // call superclass to save any view hierarchy
    super.onSaveInstanceState(outState);
}

As an alternative to defining the XML file and passing it to setContentView(), you can create new View objects in your activity code and build a view hierarchy by inserting new Views into a ViewGroup. You then use that layout by passing the root ViewGroup to setContentView(). For more information about creating a user interface, see the User Interface documentation.

作为一种替代方法来定义XML文件并将其传递到setcontentview()方法,您可以在Activity代码中创建新的视图对象并且将新视图插入到ViewGroup建立视图层次。更多关于创建用户界面的信息,请参见User Interface文档。

Your activity does not reside in the Created state. After the onCreate() method finishes execution, the activity enters the Started state, and the system calls the onStart() and onResume() methods in quick succession. The next section explains the onStart() callback.

Activity不会驻留在创建状态。在onCreate()方法执行完成之后,Activity进入开始状态,并且系统会快速回调onStart()onResume()函数。下一部分会讲解onStart()回调函数。

onStart()

When the activity enters the Started state, the system invokes this callback. The onStart() call makes the activity visible to the user, as the app prepares for the activity to enter the foreground and become interactive. For example, this method is where the app initializes the code that maintains the UI. It might also register a BroadcastReceiver that monitors changes that are reflected in the UI.

当Activity进入开始状态时,系统会调用这个回调函数。当app准备让Activity进入前台并且和用户交互的时候,onStart()方法使得Activity对用户可见。例如,此方法是app初始化代码维护UI的地方。它也可能注册一个BroadcastReceiver 去监控UI反射的变化。

The onStart() method completes very quickly and, as with the Created state, the activity does not stay resident in the Started state. Once this callback finishes, the activity enters the Resumed state, and the system invokes the onResume() method.

onStart() 方法完成是非常迅速的并且和创建状态一样,Activity不会驻留在开始状态。一旦这个回调完成,Activity会进入恢复状态,系统会调用 onResume()  方法。

onResume()

When the activity enters the Resumed state, it comes to the foreground, and then the system invokes the onResume() callback. This is the state in which the app interacts with the user. The app stays in this state until something happens to take focus away from the app. Such an event might be, for instance, receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.

当Activity进入到恢复状态是,它处于前台,之后系统会调用onResume()回调函数。这是app与用户进行交互的状态。app会停留在这个状态直到发生某些情况使得app失去焦点。这样的事件可能是:例如收到电话,用户导航至另一个Activity,或者设备屏幕关闭。

When an interruptive event occurs, the activity enters the Paused state, and the system invokes the onPause() callback.

当发生一个中断事件时,Activity会进入暂停状态,并且系统会调用onPause() 回调函数。

If the activity returns to the Resumed state from the Paused state, the system once again calls onResume() method. For this reason, you should implement onResume() to initialize components that you release during onPause(). For example, you may initialize the camera as follows:

如果Activity从暂停状态返回值恢复状态,系统会再一次调用 onResume()  方法。由于这个原因,你应该实现 onResume()方法去初始化那些你在onPause()期间释放的组件。例如,你可能会像下面这样初始化相机:


KOTLIN

override fun onResume() {
    super.onResume()

    // Get the Camera instance as the activity achieves full user focus
    if (camera == null) {
        initializeCamera() // Local method to handle camera init
    }
}

JAVA

@Override
public void onResume() {
    super.onResume();  // Always call the superclass method first

    // Get the Camera instance as the activity achieves full user focus
    if (mCamera == null) {
        initializeCamera(); // Local method to handle camera init
    }
}

Be aware that the system calls this method every time your activity comes into the foreground, including when it's created for the first time. As such, you should implement onResume() to initialize components that you release during onPause(), and perform any other initializations that must occur each time the activity enters the Resumed state. For example, you should begin animations and initialize components that the activity only uses when it has user focus.

请注意,当Activity每次进入前台的时候系统都会回调此方法,包括Activity第一次创建的时候。因此,你应该实现onResume() 方法去初始化在onPause()期间释放的组件资源,并且执行Activity进入恢复状态的必定发生的每一次的其他任何初始化。例如,你应该仅仅在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). Use the onPause() method to pause operations such animations and music playback that should not continue while the Activity is in the Paused state, and that you expect to resume shortly. There are several reasons why an activity may enter this state. For example:

系统将该方法作为用户离开Activity的第一个征兆(尽管这并不总是意味着Activity被销毁)。使用onPause() 方法去暂停一些操作如动画、当Activity在暂停状态时不应该继续播放音乐,并且你希望尽快恢复到正常状态。Activity进入该状态有这样几个原因,如下:

  • Some event interrupts app execution, as described in the onResume() section. This is the most common case.
  • 某些事件中断了app的运行,参见对onResume()描述。这是最常见的情况。
  • In Android 7.0 (API level 24) or higher, multiple apps run in multi-window mode. Because only one of the apps (windows) has focus at any time, the system pauses all of the other apps.
  • 在Android 7.0(API等级24)或者更高级别,多个app运行在多窗口模式下。由于只有一个app(windows)在任何时候都有焦点,系统会暂停其他所有app。
  • A new, semi-transparent activity (such as a dialog) opens. As long as the activity is still partially visible but not in focus, it remains paused.
  • 打开一个新的半透明Activity(例如对话框)。尽管Activity部分可见但是没有焦点,那么它停留在暂停状态。

You can use the onPause() method to release system resources, such as broadcast receivers, handles to sensors (like GPS), or any resources that may affect battery life while your activity is paused and the user does not need them.

你可以在onPause()方法中释放系统资源,例如广播接收者,处理传感器(如GPS),或者当Activity处于暂停状态并且用户不在需要它们的时候任何影响电池寿命的资源。

For example, if your application uses the Camera, the onPause() method is a good place to release it. The following example of onPause() is the counterpart to the onResume() example above, releasing the camera that the onResume() example initialized.

例如,如果你的应用使用相机,那么在 onPause()  方法中释放它是一个很好的选择。下面的onPause()例子对应上述的onResume() 例子,释放在onResume()例子中初始化的相机。

KOTLIN

override fun onPause() {
    super.onPause() // Always call the superclass method first

    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    camera?.release()
    camera = null
}

JAVA

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first

    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }
}
onPause()  execution is very brief, and does not necessarily afford enough time to perform save operations. For this reason, you should  not  use  onPause()  to save application or user data, make network calls, or execute database transactions; such work may not complete before the method completes. Instead, you should perform heavy-load shutdown operations during  onStop() . For more information about suitable operations to perform during  onStop() , see  onStop() . For more information about saving data, see  Saving and restoring activity state .

onPause()执行是非常短暂的,不会提供足够的时间去执行保存操作。因此,你不应该在onPause()方法中保存应用程序或者用户数据、进行网络调用、或者执行数据库事务;这些工作可能不会在该方法完成之前完成。相反,你应该在onStop()方法运行期间执行重负荷的关闭操作。更多关于在onStop()方法运行期间的恰当的操作请参见onStop()。更多关于保存数据的信息,请参见Saving and restoring activity state.

Completion of the onPause() method does not mean that the activity leaves the Paused state. Rather, the activity remains in this state until either the activity resumes or becomes completely invisible to the user. If the activity resumes, the system once again invokes the onResume() callback. If the activity returns from the Paused state to the Resumed state, the system keeps the Activity instance resident in memory, recalling that instance when it the system invokes onResume(). In this scenario, you don’t need to re-initialize components that were created during any of the callback methods leading up to the Resumed state. If the activity becomes completely invisible, the system calls onStop(). The next section discusses the onStop()callback.

onPause()方法的完成并不意味着Activity离开暂停状态。相反,Activity会保持这个状态直到Activity重新恢复或者对用户完全不可见。如果Activity重新恢复,系统会再一次调用onResume()回调函数。如果Activity从暂停状态返回到重新恢复状态,系统会保持Activity实例驻留内存,当系统调用onResume()方法时重新使用该实例。在这种情况下,您不需要重新初始化在恢复状态之前的任何回调方法中创建的组件。如果Activity完全不可见,系统会调用onStop()。下一部分内容讨论onStop()回调函数。

onStop()

When your activity is no longer visible to the user, it has entered the Stopped state, and the system invokes the onStop() callback. This may occur, for example, when a newly launched activity covers the entire screen. The system may also call onStop() when the activity has finished running, and is about to be terminated.

当Activity不再对用户显示,那么它就进入了停止状态,并且系统会调用 onStop()  回调函数。例如,当一个新产生的活动覆盖整个屏幕时可能会发生这种情况。当Activity运行完毕,即将终止时系统会调用onStop()方法。

In the onStop() method, the app should release almost all resources that aren't needed while the user is not using it. For example, if you registered a BroadcastReceiver in onStart() to listen for changes that might affect your UI, you can unregister the broadcast receiver in onStop(), as the user can no longer see the UI. It is also important that you use onStop() to release resources that might leak memory, because it is possible for the system to kill the process hosting your activity without calling the activity's final onDestroy() callback.

onStop()方法中,当用户不再使用app时,app应该释放几乎所有不需要的资源。例如,如果你在onStart()方法注册了一个广播接受者去监听可能影响UI的变化,当用户不再看到UI时,你可以在onStop()方法中解除注册广播接收者。同样重要的是使用onStop()方法去释放可能会引起内存泄漏的资源,因为可能系统杀死Activity的宿主进程时没有调用Activity最后的onDestroy()回调。

You should also use onStop() to perform relatively CPU-intensive shutdown operations. For example, if you can't find a more opportune time to save information to a database, you might do so during onStop(). The following example shows an implementation of onStop() that saves the contents of a draft note to persistent storage:

你应该在onStop()方法中执行相对CPU密集型的关闭操作。例如,如果你找不到一个合适的时间来保存数据到数据库,那么在onStop()运行期间进行(保存数据的操作)也是可以的。下面的例子展示了在onStop()方法中保存草稿内容到永久存储的实现:

KOTLIN

override fun onStop() {
    // call the superclass method first
    super.onStop()

    // save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    val values = ContentValues().apply {
        put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())
        put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())
    }

    // do this update in background on an AsyncQueryHandler or equivalent
    asyncQueryHandler.startUpdate(
            token,     // int token to correlate calls
            null,      // cookie, not used here
            uri,       // The URI for the note to update.
            values,    // The map of column names and new values to apply to them.
            null,      // No SELECT criteria are used.
            null       // No WHERE columns are used.
    )
}

JAVA

@Override
protected void onStop() {
    // call the superclass method first
    super.onStop();

    // save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    // do this update in background on an AsyncQueryHandler or equivalent
    mAsyncQueryHandler.startUpdate (
            mToken,  // int token to correlate calls
            null,    // cookie, not used here
            mUri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
    );
}

When your activity enters the Stopped state, the  Activity  object is kept resident in memory: It maintains all state and member information, but is not attached to the window manager. When the activity resumes, the activity recalls this information. You don’t need to re-initialize components that were created during any of the callback methods leading up to the Resumed state. The system also keeps track of the current state for each  View  object in the layout, so if the user entered text into an  EditText  widget, that content is retained so you don't need to save and restore it.

当Activity进入到停止状态时,Activity对象驻留在内存中:它维护者所有状态和成员信息,但是并不绑定到窗口管理器。当Activity重新恢复的时候,Activity会重新调用这些信息。您不需要重新初始化在恢复状态之前的任何回调方法中创建的组件。系统也会保持View对象在布局中的当前状态,所以如果用户在EditText控件中输入文本,(它的)内容会被保留,你无需去保存和恢复它。

Note: Once your activity is stopped, the system might destroy the process that contains the activity if the system needs to recover memory. Even if the system destroys the process while the activity is stopped, the system still retains the state of the View objects (such as text in an EditText widget) in a Bundle (a blob of key-value pairs) and restores them if the user navigates back to the activity. For more information about restoring an activity to which a user returns, see Saving and restoring activity state.

注意:一旦Activity停止,当系统需要恢复内存的时候(它)可能会杀死包含Activity的进程。尽管在Activity停止的时候系统杀死了(包含Activity的)进程,但是系统仍然在Bundle(一个键值对对象)里保留了View对象的状态(例如EditText的文本内容)并且如果在用户导航回到Activity的时候恢复它们。更多有关用户返回保存Activity(状态)的信息,请参见Saving and restoring activity state

From the Stopped state, the activity either comes back to interact with the user, or the activity is finished running and goes away. If the activity comes back, the system invokes onRestart(). If the Activity is finished running, the system calls onDestroy(). The next section explains the onDestroy() callback.

从停止状态起,Activity要么返回与用户进行交互,要么结束运行并且消失。如果Activity返回,系统会调用onRestart()方法。如果Activity结束运行,系统会调用onDestroy()方法。下一部分讲解onDestroy()回调方法。


onDestroy()

Called before the activity is destroyed. This is the final call that the activity receives. The system either invokes this callback because the activity is finishing due to someone's calling finish(), or because the system is temporarily destroying the process containing the activity to save space. You can distinguish between these two scenarios with the isFinishing() method. The system may also call this method when an orientation change occurs, and then immediately call onCreate() to recreate the process (and the components that it contains) in the new orientation.

该方法在Activity被销毁之前调用。这是Activity最后收到的回调。系统调用该回调函数因为Activity由于某人调用了finish()方法而结束,或者由于系统为了节省空间而临时杀死包含Activity的进程。你可以通过isFinishing()方法来区别这两种情况。当(屏幕)方向发生改变的时候系统可能会调用这个方法,并且之后立即调用onCreate()方法去在新的方向里重建进程(和它所包含的组件)。

The onDestroy() callback releases all resources that have not yet been released by earlier callbacks such as onStop().

onDestroy()回调会释放所有那些在更早没有释放资源的回调如onStop()里的资源。

Activity state and ejection from memory

Activity状态和释放内存

The system never kills an activity directly. Instead, it kills the process in which the activity runs, destroying not only the activity but everything else running in the process, as well.

系统从来不会直接杀死Activity。相反,它会杀死Activity运行所在的进程,(这样做)不仅销毁了Activity,而且也销毁了进程中的所有其他东西。

The system kills processes when it needs to free up RAM; the likelihood of its killing a given process depends on the state of the process at the time. Process state, in turn, depends on the state of the activity running in the process.

当系统需要释放内存的时候它会去杀死进程;系统杀死一个给定进程的可能性视进程当时的状态而定。进程的状态视在其中的Activity的运行状态而定。

A user can also kill a process by using the Application Manager under Settings to kill the corresponding app.

用户也可以在设置里通过使用应用管理器杀死相应app的进程。

Table 1 shows the correlation among process state, activity state, and likelihood of the system’s killing the process.

表1显示了进程状态Activity状态和系统可能杀死的进程之间的关系。

Likelihood of being killedProcess stateActivity state
LeastForeground (having or about to get focus)
前台(具有或者即将获取焦点)
Created
Started
Resumed
MoreBackground (lost focus)Paused
MostBackground (not visible)Stopped
EmptyDestroyed
Table 1. Relationship between process lifecycle and activity state

表1.进程生命周期和Activity状态之间的关系。

Navigating between activities

Activity之间的导航

An app is likely to enter and exit an activity, perhaps many times, during the app’s lifetime. For example, the user may tap the device’s Back button, or the activity may need to launch a different activity. This section covers topics you need to know to implement successful activity transitions. These topics include starting an activity from another activity, saving activity state, and restoring activity state.

在app的生命周期期间,它可能多次进入或者退出Activity。例如,用户可能会点击设备的返回按钮,或者Activity可能会启动另一个Activity。本节介绍了实现成功活动转换需要了解的主题。这些主题包括从另一个Activity启动Activity,保存和恢复Activity状态。

Starting one activity from another

从另一个Activity启动Activity

An activity often needs to start another activity at some point. This need arises, for instance, when an app needs to move from the current screen to a new one.

在某些情况下Activity需要去启动另一个Activity。例如,当应用程序需要从当前屏幕移动到新屏幕时,这种需求就会出现。

Depending on whether your activity wants a result back from the new activity it’s about to start, you start the new activity using either thestartActivity() or the startActivityForResult() method. In either case, you pass in an Intent object.

依据Activity是否想要它即将启动的来自新的Activity的返回结果,你可以使用startActivity()或者startActivityForResult()方法启动新的Activity。在以上任何情况下,你都需要传递一个Intent对象

The Intent object 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 object can also carry small amounts of data to be used by the activity that is started. For more information about the Intent class, see Intents and Intent Filters.

Intent 对象指定你想要启动的具体的Activity或者你想要执行的动作类型的描述(系统会为你选择合适的Activity,它甚至可以来自不同的应用)。 Intent对象还可以携带启动的Activity所需要的少量数据。更多有关Intent类的信息,请参见Intents and Intent Filters

startActivity()

If the newly started activity does not need to return a result, the current activity can start it by calling the startActivity() method.

When working within your own application, you often need to simply launch a known activity. For example, the following code snippet shows how to launch an activity called SignInActivity.

如果新启动的Activity不需要返回结果,那么当前Activity可以调用startActivity()方法启动它。

当在自己的应用程序中工作时,你经常需要去简单地启动一个已知的Activity。例如,下面的代码片段展示了如何去启动一个名为SignInActivity的Activity。

KOTLIN

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)

JAVA

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

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:

你的应用程序也可能想去执行一些操作,例如发送电子邮件,文本信息,或者使用来自你的Activity的数据更新状态。在这种情况下,你的应用可能没有执行上述操作的Activity,因此你可以使用该设备上其他应用的Activity来代替你的应用执行这些操作。这是Intent真正有价真的地方:你可以创建一个你想要执行的动作的描述的Intent,并且系统会从其他应用程序启动合适的Activity。如果有多个Activity可以处理这个Intent,那么应该由用户选择要使用哪个。例如,如果你想允许用户发送电子邮件信息,你可以创建如下Intent:

KOTLIN

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

JAVA

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_EMAIL被添加到Intent,它是一个去发送邮件的字符数组的邮件地址。当邮件应用程序响应这个Intent时,它读取这个额外的字符数组并将他们放到电子邮件表单的“to”字段中。在这种情况下,电子邮件应用程序的Activity启动并且当用户完成时,你的Activity重新恢复。

startActivityForResult()

Sometimes you want to get a result back from an activity when it ends. For example, you may start an activity that lets the user pick a person in a list of contacts; when it ends, it returns the person that was selected. To do this, you call the startActivityForResult(Intent, int) method, where the integer parameter identifies the call. This identifier is meant to disambiguate between multiple calls to startActivityForResult(Intent, int) from the same activity. It's not global identifier and is not at risk of conflicting with other apps or activities.The result comes back through your onActivityResult(int, int, Intent) method.

有些时候你想要从Activity获取一个返回结果当它结束的时候。例如,你可能启动一个Activity去让用户从联系人列表选择一个联系人,当Activity结束时,它会返回已经被选择的那个联系人。为了做到这一点,你需要调用 startActivityForResult(Intent, int) 方法,整型参数标识调用的位置。此标识符

用来区别来自相同Activity的对startActivityForResult(Intent, int)多次调用。它不是全局标识符,不存在与其他应用程序或活动相冲突的风险。返回结果通过onActivityResult(int, int, Intent)方法来接收。

When a child activity exits, it can call setResult(int) to return data to its parent. The child activity must always supply a result code, which can be the standard results RESULT_CANCELEDRESULT_OK, or any custom values starting at RESULT_FIRST_USER. In addition, the child activity can optionally return an Intent object containing any additional data it wants. The parent activity uses the onActivityResult(int, int, Intent) method, along with the integer identifier the parent activity originally supplied, to receive the information.

当子Activity存在时,它可以调用setResult(int)方法向父类Activity返回数据。子类Activity必须始终提供结果码,它可以是标准的结果如RESULT_CANCELED,RESULT_OK,也可以是任何从RESULT_FIRST_USER开始的自定义数值。除此之外,子Activity可以选择性的返回它想要的任何包含额外数据的Intent对象。父Activity使用onActivityResult(int, int, Intent)方法,以及最初父Activity提供的整型标识,去接收(子Activity返回的)信息。

If a child activity fails for any reason, such as crashing, the parent activity receives a result with the code RESULT_CANCELED.

如果子Activity由于任何原因失败,例如崩溃,那么父Activity会使用RESULT_CANCELED结果码接收返回结果。

JAVA

public class MyActivity extends Activity {
     // ...

     static final int PICK_CONTACT_REQUEST = 0;

     public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             // When the user center presses, let them pick a contact.
             startActivityForResult(
                 new Intent(Intent.ACTION_PICK,
                 new Uri("content://contacts")),
                 PICK_CONTACT_REQUEST);
            return true;
         }
         return false;
     }

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // A contact was picked.  Here we will just display it
                 // to the user.
                 startActivity(new Intent(Intent.ACTION_VIEW, data));
             }
         }
     }
 }

KOTLIN

class MyActivity : Activity() {
    // ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                    Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
                    PICK_CONTACT_REQUEST)
            return true
        }
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        when (requestCode) {
            PICK_CONTACT_REQUEST ->
                if (resultCode == RESULT_OK) {
                    startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
                }
        }
    }

    companion object {
        internal val PICK_CONTACT_REQUEST = 0
    }
}

Coordinating activities

协调Activity

When one activity starts another, they both experience lifecycle transitions. The first activity stops operating and enters the Paused or Stopped state, 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在第二个Activity创建之前没有完全停止是非常重要的。相反地,启动第二个Activity的进程与停止第一个Activity的进程相重叠。

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

生命周期回调的顺序是明确的,特别是当两个Activity在相同的进程(app)并且一个启动另一个时。下面是Activity A启动Activity B时发生的操作顺序:

1.Activity A's onPause() method executes.

    Activity A的onPause()方法执行。

2.Activity B's onCreate()onStart(), and onResume() methods execute in sequence. (Activity B now has user focus.)

    Activity B的onCreate()onStart(), 和 onResume()方法依次执行。(Activity B现在拥有用户焦点。)

3.Then, if Activity A is no longer visible on screen, its onStop() method executes.

    然后,如果Activity A不再在屏幕上显示,那么它的onStop()方法将会执行。

This predictable sequence of lifecycle callbacks allows you to manage the transition of information from one activity to another.

这个预先指定的顺序,允许你管理从一个Activity到另一个的信息传输。

Saving and restoring activity state

保存和恢复Activity状态

There are a few scenarios in which your activity is destroyed due to normal app behavior, such as when the user presses the Back button or your activity signals its own destruction by calling the finish() method. The system may also destroy the process containing your activity to recover memory if the activity is in the Stopped state and hasn't been used in a long time, or if the foreground activity requires more resources.

一些情况下Activity是由于正常的app行为而被销毁,例如用户按下返回按钮或者Activity自己调用finish()销毁自己。如果Activity处于停止状态并且很长一段时间没有被使用,或者前台Activity需要更多的资源,在这些情况下系统可能会销毁包含Activity的进程去恢复内存。

When your activity is destroyed because the user presses Back or the activity finishes itself, the system's concept of that Activity instance is gone forever because the behavior indicates the activity is no longer needed. However, if the system destroys the activity due to system constraints (rather than normal app behavior), then although the actual Activity instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed. The saved data that the system uses to restore the previous state is called the instance state and is a collection of key-value pairs stored in a Bundle object.

当Activity由于用户按下返回键或者Activity调用finish方法被销毁时,Activity实例的系统概念将永远消失,因为(按下返回键的)行为表明此Activity不再被需要。然而,如果由于系统约束而销毁Activity(而不是正常的app行为),那么尽管实际的Activity实例消失了,但是如果用户返回这个Activity时系统仍会记得它的存在,系统会创建一个新的Activity实例去使用当Activity被销毁时保存的描述状态的数据。系统用于恢复以前状态的保存数据叫做实例状态,它是存储在Bundle对象中的一个键值对集合。

By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText widget). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.

默认情况下,系统使用Bundle实例状态去保存Activity布局中的每个View对象的信息(例如文本进入到EditText控件中)。所以,如果你的Activity实例被销毁并且被重建,布局状态不需要来自你的代码去恢复它以前的状态。然而,Activity可能会还原更多你希望恢复的信息,例如跟踪Activity中用户进度的成员变量。

Bundle object isn't appropriate for preserving more than a trivial amount of data because it consumes system-process memory. To preserve more than a very small amount of data, you should take a combined approach to preserving data, using persistent local storage, the onSaveInstanceState() method, and the ViewModel class. For more information about preserving complex data structures, see Saving UI States.

Bundle对象不适合去保存小数量的数据因为它会消耗系统级进程内存。为了保存小数量数据,你需要使用onSaveInstanceState()方法和ViewModel类这些本地持久化存储去保存他们。更多有关保存复杂数据架构的信息,请参见Saving UI States

For cases where a Bundle is appropriate, you may use the onSaveInstanceState() method. The next section provides detail about how to use this method.

为了在合适的情形下使用Bundle,你可能会使用onSaveInstanceState()方法。下一部分提供关于如何使用这个方法的详细介绍。

Save your activity state

保存Activity状态

As your activity begins to stop, the system calls the onSaveInstanceState() method so your activity can save state information with a collection of key-value pairs. The default implementation of this method saves transient information about the state of the activity's view hierarchy, such as the text in an EditText widget or the scroll position of a ListView widget. Your app should implement the onSaveInstanceState() callback after the onPause() method, and before  onStop(). Do not implement this callback in onPause().

当Activity开始停止时,系统会调用 onSaveInstanceState()方法,因此你可以使用一个键值对集合保存Activity的状态信息。此方法的默认实现保存关于Activity的视图层次结构状态的瞬态信息,例如 EditText控件的文本或者 ListView控件的滑动位置。app应该在 onPause()方法之后, onStop()之前实现 onSaveInstanceState()回调。不要在 onPause()方法里面实现该回调。

Caution: You must always call the superclass implementation of onSaveInstanceState() so the default implementation can save the state of the view hierarchy.

当心:你必须实现父类的onSaveInstanceState()方法,因为默认实现可以保存视图层级状态。

To save additional state information for your activity, you must override onSaveInstanceState() and add key-value pairs to the Bundle object that is saved in the event that your activity is destroyed unexpectedly. For example:

为了保存Activity的额外信息,你必须复写onSaveInstanceState()方法并且添加键值对到Bundle对象中去保存Activity被意外销毁的事件,例如:

KOTLIN

override fun onSaveInstanceState(outState: Bundle?) {
    // Save the user's current game state
    outState?.run {
        putInt(STATE_SCORE, currentScore)
        putInt(STATE_LEVEL, currentLevel)
    }


    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(outState)
}

companion object {
    val STATE_SCORE = "playerScore"
    val STATE_LEVEL = "playerLevel"
}

JAVA

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
    savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);


    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}
Note:  In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the  android:id  attribute.

注意:为了让Android系统恢复Activity中视图的状态,每个视图必须有唯一的由android:id提供的ID。

To save persistent data, such as user preferences or data for a database, you should take appropriate opportunities when your activity is in the foreground. If no such opportunity arises, you should save such data during the onStop() method.

为了保存永久数据,例如数据库的用户首选项或数据,当Activity在前台的时候,你应该选择合适的机会去做(这件事)。如果没有这样的机会,你应该在onStop()方法中保存数据。

Restore your activity state

恢复Activity状态

When your activity is recreated after it was previously destroyed, you can recover your saved state from the Bundle that the system passes to your activity. Both the onCreate() and onRestoreInstanceState() callback methods receive the same Bundle that contains the instance state information.

当Activity是重建之前被销毁的时,系统会通过Activity去恢复(之前)保存的状态。onCreate()onRestoreInstanceState()都可以接收相同的包含实力状态信息的Bundle。因为

Because the onCreate() method is called whether the system is creating a new instance of your activity or recreating a previous one, you must check whether the state Bundle is null before you attempt to read it. If it is null, then the system is creating a new instance of the activity, instead of restoring a previous one that was destroyed.

因为onCreate()方法无论是在系统创建新的Activity实例还是重建之前的Activity实例,它都会被调用,所以在尝试读取它(Bundle)的时候必须检查Bundle状态是否为空,如果为空,系统会创建一个新的Activity实例,而不是恢复之前被销毁的那个(Activity实例)。

For example, the following code snippet shows how you can restore some state data in onCreate():

例如,以下代码片段展示了如何在onCreate()中储存一些状态数据:

KOTLIN

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState) // Always call the superclass first


    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        with(savedInstanceState) {
            // Restore value of members from saved state
            currentScore = getInt(STATE_SCORE)
            currentLevel = getInt(STATE_LEVEL)
        }
    } else {
        // Probably initialize members with default values for a new instance
    }
    // ...
}

JAVA

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first


    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance
    }
    // ...
}
Instead of restoring the state during  onCreate()  you may choose to implement  onRestoreInstanceState() , which the system calls after the  onStart() method. The system calls  onRestoreInstanceState()  only if there is a saved state to restore, so you do not need to check whether the  Bundle  is null:

你可能选择在onRestoreInstanceState()方法里去实现恢复状态操作而不是在onCreate()执行期间,它(onRestoreInstanceState())在onStart()方法之后被系统调用。如果有保存的状态需要恢复,那么系统仅仅会调用onRestoreInstanceState()方法去恢复它,所以你不需要去检查Bundle是否为空:

KOTLIN

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState)

    // Restore state members from saved instance
    savedInstanceState?.run {
        currentScore = getInt(STATE_SCORE)
        currentLevel = getInt(STATE_LEVEL)
    }
}

JAVA

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
Caution: Always call the superclass implementation of  onRestoreInstanceState()  so the default implementation can restore the state of the view hierarchy.
注意:你总是需要 onRestoreInstanceState()方法的父类实现因为默认的实现能够恢复视图对象的层级状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值