Жизненный цикл действияActivity Lifecycle

Действия являются основной строительный блок рабочих приложений Android, и они могут присутствовать в нескольких различных состояний. Жизненный цикл действия начинается с создания экземпляра и заканчивается уничтожение и включает много состояний между ними. При изменении состояния действия соответствующие жизненного цикла события вызове метода уведомления активности внесение изменений состояния и позволяя ему для выполнения кода, чтобы адаптироваться к это изменение. В этой статье рассматриваются жизненного цикла действий и объясняется ответственность за наличие действия выполнения каждой из этих изменений как часть долгосрочных, надежные приложения.Activities are a fundamental building block of Android applications and they can exist in a number of different states. The activity lifecycle begins with instantiation and ends with destruction, and includes many states in between. When an activity changes state, the appropriate lifecycle event method is called, notifying the activity of the impending state change and allowing it to execute code to adapt to that change. This article examines the lifecycle of activities and explains the responsibility that an activity has during each of these state changes to be part of a well-behaved, reliable application.

Обзор жизненного цикла действияActivity Lifecycle Overview

Действия являются необычные понятие программирования для Android.Activities are an unusual programming concept specific to Android. В процесс разработки традиционных приложений обычно имеется статический метод main, который выполняется для запуска приложения.In traditional application development there is usually a static main method, which is executed to launch the application. С Android Однако все по-другому; Приложения Android можно запустить с помощью любого зарегистрированного действия в приложении.With Android, however, things are different; Android applications can be launched via any registered activity within an application. На практике большинство приложений имеют только определенное действие, заданным как точку входа приложения.In practice, most applications will only have a specific activity that is specified as the application entry point. Тем не менее, если приложение аварийно завершает работу, или прерывается, операционной системы, ОС может попытаться перезапустить приложения на последнее действие open или в любом месте стеке предыдущего действия.However, if an application crashes, or is terminated by the OS, the OS can try to restart the application at the last open activity or anywhere else within the previous activity stack. Кроме того ОС может приостановки действий в том случае, если они не active и их восстановления, если он не хватает памяти.Additionally, the OS may pause activities when they're not active, and reclaim them if it is low on memory. Чтобы разрешить приложению правильно восстановить свое состояние в случае, если действие перезапуска, особенно в том случае, если, действие зависит от данных из предыдущих действий должны выполняться тщательного анализа.Careful consideration must be made to allow the application to correctly restore its state in the event that an activity is restarted, especially if that activity depends on data from previous activities.

Жизненный цикл действия реализуется как коллекция вызовов методов операционной системы на протяжении жизненного цикла действия.The activity lifecycle is implemented as a collection of methods the OS calls throughout the lifecycle of an activity. Эти методы позволяют разработчикам реализовать функциональные возможности, необходимые для удовлетворения требований управления состояния и ресурсов приложений.These methods allow developers to implement the functionality that is necessary to satisfy the state and resource management requirements of their applications.

Очень важно для разработчиков приложений для анализа требования каждого действия, чтобы определить, какие методы, предоставляемые жизненный цикл действия должны быть реализованы.It is extremely important for the application developer to analyze the requirements of each activity to determine which methods exposed by the activity lifecycle need to be implemented. Если этого не сделать может привести к нестабильной работе приложения, сбои, Раздувание ресурсов и нестабильности даже базовой операционной системы.Failure to do this can result in application instability, crashes, resource bloat, and possibly even underlying OS instability.

В этой главе рассматриваются жизненный цикл действия подробно, включая:This chapter examines the activity lifecycle in detail, including:

  • Состояния действияActivity States
  • Методы жизненного циклаLifecycle Methods
  • Сохранение состояния приложенияRetaining the State of an Application

Этот раздел также содержит Пошаговое руководство о том, как для эффективного сохранения состояния во время жизненный цикл действия, которые предоставляют практические примеры.This section also includes a walkthrough that provide practical examples on how to efficiently save state during the Activity lifecycle. В конце данной главы необходимо понимание жизненный цикл действия и как его поддерживать в приложении Android.By the end of this chapter you should have an understanding of the Activity lifecycle and how to support it in an Android application.

Жизненный цикл действияActivity Lifecycle

Жизненный цикл действия Android состоит из набора методов, предоставляемых в рамках класса действия, которые предоставляют разработчику архитектура управления ресурсами.The Android activity lifecycle comprises a collection of methods exposed within the Activity class that provide the developer with a resource management framework. Эта платформа позволяет разработчикам требованиям управления уникальное состояние каждого действия в приложении и правильно обрабатывать управления ресурсами.This framework allows developers to meet the unique state management requirements of each activity within an application and properly handle resource management.

Состояния действияActivity States

ОС Android выполняет оценку действий в зависимости от их состояния.The Android OS arbitrates Activities based on their state. Это помогает выявить действия, которые больше не используются, позволяя операционной системы для освобождения памяти и ресурсов Android.This helps Android identify activities that are no longer in use, allowing the OS to reclaim memory and resources. На следующей схеме состояний, которые можно выполнить действие во время существования:The following diagram illustrates the states an Activity can go through during its lifetime:

Схема состояния активностиActivity states diagram

Эти состояния можно разбить на 4 группы следующим образом:These states can be broken into 4 main groups as follows:

  1. Активные или запущенные – рассматриваемые активный или выполнения, если они находятся на переднем плане, называемые также верхней части стека действие действия.Active or Running – Activities are considered active or running if they are in the foreground, also known as the top of the activity stack. Это считается наибольшей активности приоритет в Android и таким образом будет только завершить операционной системы в чрезвычайных ситуациях, таких как, если действие пытается использовать больше памяти, чем доступно на устройстве, так как это может вызвать зависание пользовательского интерфейса.This is considered the highest priority activity in Android, and as such will only be killed by the OS in extreme situations, such as if the activity tries to use more memory than is available on the device as this could cause the UI to become unresponsive.

  2. Приостановлено – когда устройство переходит в спящий режим или действия по-прежнему отображаются, но частично скрыт на основе новых, отличных от полноразмерные или прозрачное действие, действие считается приостановлена.Paused – When the device goes to sleep, or an activity is still visible but partially hidden by a new, non-full-sized or transparent activity, the activity is considered paused. Приостановленное действия находятся все еще существует, то есть они обеспечивают всю информацию о состоянии и член и будет прикреплен к, чтобы диспетчер окон.Paused activities are still alive, that is, they maintain all state and member information, and remain attached to the window manager. Это рассматривается как второй наивысший приоритет действия в Android и, таким образом, будут прерваны в ОС, только если завершение этого действия будет удовлетворять требования к ресурсам, нужно четко активный/запущенное действие стабильной и отвечает на запросы.This is considered to be the second highest priority activity in Android and, as such, will only be killed by the OS if killing this activity will satisfy the resource requirements needed to keep the Active/Running Activity stable and responsive.

  3. Остановить/Backgrounded – действий, которые полностью скрыт другим действием, считаются остановлен или в фоновом режиме.Stopped/Backgrounded – Activities that are completely obscured by another activity are considered stopped or in the background. Остановлена действий по-прежнему пытаться сохранить их состояние и сведения о члене для, пока считается, что возможно, но остановленное действий являются самым низким приоритетом из трех состояний, и, таким образом, операционная система будет kill действий в этом состоянии, во-первых, для удовлетворения ресурса требования к более высоким приоритетом действий.Stopped activities still try to retain their state and member information for as long as possible, but stopped activities are considered to be the lowest priority of the three states and, as such, the OS will kill activities in this state first to satisfy the resource requirements of higher priority activities.

  4. Перезапустить – это возможно, для действия, который лежит в интервале от приостановлена до остановки в жизненном цикле, удаляются из памяти системой Android.Restarted – It is possible for an activity that is anywhere from paused to stopped in the lifecycle to be removed from memory by Android. Если пользователь переходит обратно к операции, к которой он должен быть перезапущен, восстановить его ранее сохраненное состояние, а затем отображаются для пользователя.If the user navigates back to the activity it must be restarted, restored to its previously saved state, and then displayed to the user.

Повторное создание действия в ответ на изменения конфигурацииActivity Re-Creation in Response to Configuration Changes

Чтобы сделать сложнее: вопросы и ответы, Android создает один дополнительные гаечного ключа в наборе, вызывается изменения конфигурации.To make matters more complicated, Android throws one more wrench in the mix called Configuration Changes. Изменения конфигурации выполняется быстрое действие удаления или повторно-creation циклов, возникающих при изменении конфигурации действия, например, если устройство повернутый (и действие должно быть повторно создан в альбомной или книжной ориентации режим), при отображении клавиатуры (и действия предоставляется возможность изменять размер), или при помещении устройства в закрепления, среди прочего.Configuration changes are rapid activity destruction/re-creation cycles that occur when the configuration of an activity changes, such as when the device is rotated (and the activity needs to get re-built in landscape or portrait mode), when the keyboard is displayed (and the activity is presented with an opportunity to resize itself), or when the device is placed in a dock, among others.

Изменения конфигурации по-прежнему вызывать те же изменения состояния действия, которые произошли бы во время остановки и перезапуска действие.Configuration changes still cause the same Activity State changes that would occur during stopping and restarting an activity. Тем не менее чтобы убедиться в том, что приложение, в том числе быстрые и выполняет также во время изменения конфигурации, очень важно, они обрабатываются как можно быстрее.However, in order to make sure that an application feels responsive and performs well during configuration changes, it's important that they are handled as quickly as possible. По этой причине Android имеет определенный интерфейс API, который может использоваться для сохранения состояния во время изменения конфигурации.Because of this, Android has a specific API that can be used to persist state during configuration changes. Мы рассмотрим это позднее в управление состоянии на протяжении всего жизненного цикла раздел.We'll cover this later in the Managing State Throughout the Lifecycle section.

Методы жизненного цикла действияActivity Lifecycle Methods

Пакет SDK для Android и по расширению, Xamarin.Android framework предоставляют мощную модель для управления состоянием действий в приложении.The Android SDK and, by extension, the Xamarin.Android framework provide a powerful model for managing the state of activities within an application. При изменении состояния действия, действие получает уведомление в ОС, который вызывает конкретные методы для этого действия.When an activity's state is changing, the activity is notified by the OS, which calls specific methods on that activity. На следующей схеме показана этих методов по отношению к их жизненный цикл:The following diagram illustrates these methods in relation to the Activity Lifecycle:

Блок-схема жизненного цикла действияActivity Lifecycle flowchart

Как разработчик может обрабатывать изменения состояния, переопределив эти методы в рамках действия.As a developer, you can handle state changes by overriding these methods within an activity. Важно отметить, что все методы жизненного цикла вызываются в потоке пользовательского интерфейса и заблокирует ОС от выполнения создается следующая часть работы пользовательского интерфейса, например, для скрытия текущим действием, отображение нового действия и т. д. Таким образом код в этих методах должен быть достаточно кратким вы хорошо работает приложение.It's important to note, however, that all lifecycle methods are called on the UI thread and will block the OS from performing the next piece of UI work, such as hiding the current activity, displaying a new activity, etc. As such, code in these methods should be as brief as possible to make an application feel well performing. Любой длительно выполняемых задач должна выполняться в фоновом потоке.Any long-running tasks should be executed on a background thread.

Давайте рассмотрим каждое из этих методов жизненного цикла и их использования:Let's examine each of these lifecycle methods and their use:

OnCreateOnCreate

OnCreate — это первый метод, вызываемый при создании действия.OnCreate is the first method to be called when an activity is created. OnCreate всегда переопределяется для инициализаций запуска, которые могут быть действием такие как:OnCreate is always overridden to perform any startup initializations that may be required by an Activity such as:

  • Создание представленийCreating views
  • Инициализация переменныхInitializing variables
  • Привязка к спискам статических данныхBinding static data to lists

OnCreate принимает пакета параметр, который представляет собой словарь для хранения и передачи сведений о состоянии и объектов между действиями, если пакет не равно null, это указывает, перезапускается действия и его следует восстановить свое состояние из предыдущий экземпляр.OnCreate takes a Bundle parameter, which is a dictionary for storing and passing state information and objects between activities If the bundle is not null, this indicates the activity is restarting and it should restore its state from the previous instance. Следующий код иллюстрирует способ извлечения значений из пакета:The following code illustrates how to retrieve values from the bundle:

protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);

   string intentString;
   bool intentBool;

   if (bundle != null)
   {
      intentString = bundle.GetString("myString");
      intentBool = bundle.GetBoolean("myBool");
   }

   // Set our view from the "main" layout resource
   SetContentView(Resource.Layout.Main);
}

Один раз OnCreate имеет завершена, будет вызывать Android OnStart.Once OnCreate has finished, Android will call OnStart.

OnStartOnStart

OnStart всегда вызывается системой после OnCreate завершения работы.OnStart is always called by the system after OnCreate is finished. Действия могут переопределить этот метод, если им необходим для выполнения какого-либо права конкретные задачи, прежде чем действие становится видимым, такие как обновление текущие значения представлений в пределах действия.Activities may override this method if they need to perform any specific tasks right before an activity becomes visible such as refreshing current values of views within the activity. Android будет вызывать OnResume сразу же после этого метода.Android will call OnResume immediately after this method.

OnResumeOnResume

Системные вызовы OnResume когда действия будет готов начать взаимодействие с пользователем.The system calls OnResume when the Activity is ready to start interacting with the user. Действия должны переопределять этот метод для выполнения задач, таких как:Activities should override this method to perform tasks such as:

  • Медленное повышение частоты кадров (обычная задача в разработке игр)Ramping up frame rates (a common task in game development)
  • Запуск анимацииStarting animations
  • Ожидание обновления GPSListening for GPS updates
  • Отображаются соответствующие оповещения и диалоговые окнаDisplay any relevant alerts or dialogs
  • Связывать обработчики внешних событийWire up external event handlers

Например в следующем фрагменте кода показано, как инициализировать камеры:As an example, the following code snippet shows how to initialize the camera:

public void OnResume()
{
    base.OnResume(); // Always call the superclass first.

    if (_camera==null)
    {
        // Do camera initializations here
    }
}

OnResume тем, что любая операция, в OnPause должно быть не делать OnResume, так как это единственный метод жизненного цикла, которое гарантированно будет выполняться OnPause при переводе действие обратно в жизнь.OnResume is important because any operation that is done in OnPause should be un-done in OnResume, since it's the only lifecycle method that is guaranteed to execute after OnPause when bringing the activity back to life.

OnPauseOnPause

OnPause вызывается, когда система пытается поместить действие в фоновом режиме или в случаях, когда действие становится частично закрыт.OnPause is called when the system is about to put the activity into the background or when the activity becomes partially obscured. Действия должны переопределить этот метод, если им необходимо:Activities should override this method if they need to:

  • Зафиксировать несохраненные изменения в постоянных данныхCommit unsaved changes to persistent data

  • Уничтожения или очистка других объектов потребления ресурсовDestroy or clean up other objects consuming resources

  • Собственный частоты кадров и приостановка анимацииRamp down frame rates and pausing animations

  • Отменить регистрацию обработчиков внешнего события или обработчики для уведомляющих (т. е. те, которые привязаны к службе).Unregister external event handlers or notification handlers (i.e. those that are tied to a service). Это необходимо сделать для предотвращения утечек памяти действия.This must be done to prevent Activity memory leaks.

  • Аналогично, если действие отображается, никакие диалоговые окна или оповещения, они должны удаляться с .Dismiss() метод.Likewise, if the Activity has displayed any dialogs or alerts, they must be cleaned up with the .Dismiss() method.

Например, следующий фрагмент кода будет освобождать камеры, как действие не может вносить использовать его во время паузы:As an example, the following code snippet will release the camera, as the Activity cannot make use of it while paused:

public void OnPause()
{
    base.OnPause(); // Always call the superclass first

    // Release the camera as other activities might need it
    if (_camera != null)
    {
        _camera.Release();
        _camera = null;
    }
}

Существует два возможных жизненный цикл метода, которые будут вызываться после OnPause:There are two possible lifecycle methods that will be called after OnPause:

  1. OnResume будет вызываться, если действие должно возвращаться на передний план.OnResume will be called if the Activity is to be returned to the foreground.
  2. OnStop будет вызываться, если действие помещается в фоновом режиме.OnStop will be called if the Activity is being placed in the background.

OnStopOnStop

OnStop вызывается, когда действие больше не отображается для пользователя.OnStop is called when the activity is no longer visible to the user. Это происходит, когда происходит одно из следующих:This happens when one of the following occurs:

  • Новое действие запускается и закрывающий это действие.A new activity is being started and is covering up this activity.
  • Существующее действие переводится на передний план.An existing activity is being brought to the foreground.
  • Действие уничтожается.The activity is being destroyed.

OnStop не всегда можно вызывать в ситуациях нехватки памяти, например, если нехватка ресурсов Android и не может правильно фоновое действие.OnStop may not always be called in low-memory situations, such as when Android is starved for resources and cannot properly background the Activity. По этой причине лучше не полагаться на OnStop получение называется при подготовке действие для удаления.For this reason, it is best not to rely on OnStop getting called when preparing an Activity for destruction. Далее методы жизненного цикла, которые могут быть вызваны после этого будет OnDestroy Если действие выходит из употребления, или OnRestart Если действия возвращается для взаимодействия с пользователем.The next lifecycle methods that may be called after this one will be OnDestroy if the Activity is going away, or OnRestart if the Activity is coming back to interact with the user.

onDestroyOnDestroy

OnDestroy — последний метод, который вызывается для экземпляра действия, прежде чем он уничтожен и полностью удаляется из памяти.OnDestroy is the final method that is called on an Activity instance before it's destroyed and completely removed from memory. В чрезвычайных ситуациях Android может завершить процесс приложения, на котором размещается действие, которое приведет к OnDestroy не вызывается.In extreme situations Android may kill the application process that is hosting the Activity, which will result in OnDestroy not being invoked. Большинство действий не будет реализовывать этот метод, так как большинство очистки и завершение работы было сделано OnPause и OnStop методы.Most Activities will not implement this method because most clean up and shut down has been done in the OnPause and OnStop methods. OnDestroy Метод обычно переопределяется для очистки долго выполняющего ресурсы могут допускать утечку ресурсов.The OnDestroy method is typically overridden to clean up long running resources that might leak resources. Примером этого может быть фоновым потокам, которые были запущены в OnCreate.An example of this might be background threads that were started in OnCreate.

Будет существовать методы жизненного цикла, не вызывается после уничтожения действия.There will be no lifecycle methods called after the Activity has been destroyed.

OnRestartOnRestart

OnRestart вызывается после того, действие было остановлено, то перед его повторном запуске.OnRestart is called after your activity has been stopped, prior to it being started again. Хорошим примером этого бы в том случае, когда пользователь нажимает кнопки домашней страницы в действие в приложении.A good example of this would be when the user presses the home button while on an activity in the application. В этом случае OnPause и затем OnStop методы вызываются, и действия, перемещаются в фоновом режиме, но не уничтожается.When this happens OnPause and then OnStop methods are called, and the Activity is moved to the background but is not destroyed. Если бы пользователь, а затем для восстановления приложения с помощью диспетчера задач или аналогичного приложения, вызовет Android OnRestart метод действия.If the user were then to restore the application by using the task manager or a similar application, Android will call the OnRestart method of the activity.

Существует общих принципов какого рода логики должны быть реализованы в OnRestart.There are no general guidelines for what kind of logic should be implemented in OnRestart. Это обусловлено OnStart всегда вызывается независимо от того, создается ли действие или перезапустить, чтобы все ресурсы, необходимые действия, которые должны быть инициализированы в OnStart, а не OnRestart.This is because OnStart is always invoked regardless of whether the Activity is being created or being restarted, so any resources required by the Activity should be initialized in OnStart, rather than OnRestart.

Далее метод жизненного цикла, вызванный после OnRestart будет OnStart.The next lifecycle method called after OnRestart will be OnStart.

Обратно vs. Главная страницаBack vs. Home

На многих устройствах Android имеется две отдельных кнопки: кнопка «Назад» и кнопка «Главная».Many Android devices have two distinct buttons: a "Back" button and a "Home" button. Пример этого можно увидеть на следующем снимке экрана из Android 4.0.3:An example of this can be seen in the following screenshot of Android 4.0.3:

Кнопки домашней назад иBack and Home buttons

Есть небольшая разница между двумя кнопками, несмотря на то, что у них могут иметь один и тот же эффект размещения приложения в фоновом режиме.There is a subtle difference between the two buttons, even though they appear to have the same effect of putting an application in the background. Когда пользователь щелкает кнопку "Назад", они говорят Android, что они выполняются с действием.When a user clicks the Back button, they are telling Android that they are done with the activity. Android будет уничтожена действия.Android will destroy the Activity. Напротив, при нажатии кнопки домашней страницы действие просто помещается в фоновом режиме – Android не прервет действие.In contrast, when the user clicks the Home button the activity is merely placed into the background – Android will not kill the activity.

Управление состоянием на протяжении жизненного циклаManaging State Throughout the Lifecycle

При действие остановлена или уничтожения система предоставляет возможность сохранения состояния действия для более поздней версии расконсервации.When an Activity is stopped or destroyed the system provides an opportunity to save the state of the Activity for later rehydration. Это сохраненное состояние называется состояние экземпляра.This saved state is referred to as instance state. Android предоставляет три способа хранения состояния экземпляра во время их жизненный цикл:Android provides three options for storing instance state during the Activity lifecycle:

  1. Хранение значений-примитивов в Dictionary называется пакета что Android будет использовать для сохранения состояния.Storing primitive values in a Dictionary known as a Bundle that Android will use to save state.

  2. Создание пользовательского класса, который будет содержать сложные значения, такие как растровые изображения.Creating a custom class that will hold complex values such as bitmaps. Android будет использовать этот пользовательский класс для сохранения состояния.Android will use this custom class to save state.

  3. Обход управления жизненным циклом конфигураций изменений и при условии, что полный ответственность за поддержание состояния в действии.Circumventing the configuration change lifecycle and assuming complete responsibility for maintaining state in the activity.

В этом руководстве описывается первые два варианта.This guide covers the first two options.

Состояние пакетаBundle State

Основной параметр для сохранения состояния экземпляра, — использовать объект словарь ключей и значений, известный как пакета.The primary option for saving instance state is to use a key/value dictionary object known as a Bundle. Помните, что при создании действия, OnCreate метод передается пакет в качестве параметра, этот пакет можно использовать для восстановления состояния экземпляра.Recall that when an Activity is created that the OnCreate method is passed a bundle as a parameter, this bundle can be used to restore the instance state. Не рекомендуется использовать пакет для более сложных данных, которые не быстро и легко сериализовать в пары (например, растровые изображения); "ключ значение" Вместо этого он должен использоваться для простых значений, таких как строки.It is not recommended to use a bundle for more complex data that won't quickly or easily serialize to key/value pairs (such as bitmaps); rather, it should be used for simple values like strings.

Действие предоставляет методы для сохранения и извлечения состояния экземпляра в пакете:An Activity provides methods to help with saving and retrieving the instance state in the Bundle:

  • OnSaveInstanceState – вызывается с Android при уничтожении действия.OnSaveInstanceState – This is invoked by Android when the activity is being destroyed. Действия можно реализовать этот метод, если им необходимо сохранять все элементы состояния ключ/значение.Activities can implement this method if they need to persist any key/value state items.

  • OnRestoreInstanceState – это называется после OnCreate метод завершения и предоставляет еще одна возможность для действия восстановить свое состояние после завершения установки.OnRestoreInstanceState – This is called after the OnCreate method is finished, and provides another opportunity for an Activity to restore its state after initialization is complete.

На следующей схеме показана, как используются эти методы:The following diagram illustrates how these methods are used:

Блок-схема состояния пакетаBundle states flowchart

OnSaveInstanceStateOnSaveInstanceState

OnSaveInstanceState будет вызываться, как выполняется остановка действия.OnSaveInstanceState will be called as the Activity is being stopped. Он будет получать действия можно хранить в состояние параметра пакета.It will receive a bundle parameter that the Activity can store its state in. При изменении конфигурации устройства, можно использовать действие Bundle объект, переданный для сохранения состояния действия путем переопределения OnSaveInstanceState.When a device experiences a configuration change, an Activity can use the Bundle object that is passed in to preserve the Activity state by overriding OnSaveInstanceState. Рассмотрим следующий пример кода:For example, consider the following code:

int c;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  this.SetContentView (Resource.Layout.SimpleStateView);

  var output = this.FindViewById<TextView> (Resource.Id.outputText);

  if (bundle != null) {
    c = bundle.GetInt ("counter", -1);
  } else {
    c = -1;
  }

  output.Text = c.ToString ();

  var incrementCounter = this.FindViewById<Button> (Resource.Id.incrementCounter);

  incrementCounter.Click += (s,e) => {
    output.Text = (++c).ToString();
  };
}

В приведенном выше коде увеличивает целочисленное именованное c при кнопки с именем incrementCounter нажатии вывод результата в TextView с именем output.The code above increments an integer named c when a button named incrementCounter is clicked, displaying the result in a TextView named output. Когда происходит изменение конфигурации — например, при повороте устройства — приведенный выше код будет утеряна значение c поскольку bundle бы null, как показано на рисунке ниже:When a configuration change happens - for example, when the device is rotated - the above code would lose the value of c because the bundle would be null, as shown in the figure below:

Не отображаются предыдущее значениеDisplay does not show previous value

Чтобы сохранить значение c в этом примере можно переопределить действия OnSaveInstanceState, сохраняя значения в наборе, как показано ниже:To preserve the value of c in this example, the Activity can override OnSaveInstanceState, saving the value in the bundle as shown below:

protected override void OnSaveInstanceState (Bundle outState)
{
  outState.PutInt ("counter", c);
  base.OnSaveInstanceState (outState);
}

Теперь при повороте устройства для принятия новой ориентации, целочисленное значение сохраняется в пакете и извлекается с помощью строки:Now when the device is rotated to a new orientation, the integer is saved in the bundle and is retrieved with the line:

c = bundle.GetInt ("counter", -1);

Примечание

Это важно всегда вызов базовой реализации OnSaveInstanceState таким образом, чтобы состояние иерархии представления также могут сохраняться.It is important to always call the base implementation of OnSaveInstanceState so that the state of the view hierarchy can also be saved.

Состояние представленияView State

Переопределение OnSaveInstanceState представляет собой соответствующий механизм для сохранения временных данных в действие через изменения ориентации, например счетчика в приведенном выше примере.Overriding OnSaveInstanceState is an appropriate mechanism for saving transient data in an Activity across orientation changes, such as the counter in the above example. Однако реализация по умолчанию OnSaveInstanceState позаботится о сохранении временных данных в пользовательском Интерфейсе для каждого представления до тех пор, пока каждое представление имеет идентификатор, назначенный.However, the default implementation of OnSaveInstanceState will take care of saving transient data in the UI for every view, so long as each view has an ID assigned. Предположим, например, приложение имеет EditText элемент, определенный в формате XML следующим образом:For example, say an application has an EditText element defined in XML as follows:

<EditText android:id="@+id/myText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"/>

Так как EditText элемент управления имеет id назначено, когда пользователь вводит некоторые данные и повороте устройства, данные по-прежнему отображаются, как показано ниже:Since the EditText control has an id assigned, when the user enters some data and rotates the device, the data is still displayed, as shown below:

Данные сохраняются в альбомной ориентацииData is preserved in landscape mode

OnRestoreInstanceStateOnRestoreInstanceState

OnRestoreInstanceState будет вызываться после OnStart.OnRestoreInstanceState will be called after OnStart. Он предоставляет возможность восстанавливать состояния, который был ранее сохранен пакет во время предыдущего действия OnSaveInstanceState.It provides an activity the opportunity to restore any state that was previously saved to a Bundle during the previous OnSaveInstanceState. Это связано с тем же пакета, который предоставляется OnCreate, но при этом.This is the same bundle that is provided to OnCreate, however.

В следующем коде показано, как можно восстановить состояние OnRestoreInstanceState:The following code demonstrates how state can be restored in OnRestoreInstanceState:

protected override void OnRestoreInstanceState(Bundle savedState)
{
    base.OnRestoreSaveInstanceState(savedState);
    var myString = savedState.GetString("myString");
    var myBool = savedState.GetBoolean("myBool");
}

Этот метод используется для обеспечения дополнительных возможностей вокруг в том случае, когда состояние должно быть восстановлено.This method exists to provide some flexibility around when state should be restored. Иногда бывает более подходящим решением может подождать, пока все операции инициализации выполняются перед восстановлением состояния экземпляра.Sometimes it is more appropriate to wait until all initializations are done before restoring instance state. Кроме того подкласс существующее действие может требоваться только восстановить определенные значения из состояния экземпляра.Additionally, a subclass of an existing Activity may only want to restore certain values from the instance state. Во многих случаях это не требуется переопределять OnRestoreInstanceState, так как большинство действий можно восстановить состояние, с помощью пакета для OnCreate.In many cases, it's not necessary to override OnRestoreInstanceState, since most activities can restore state using the bundle provided to OnCreate.

Пример сохранения состояния с помощью Bundle, см. Пошаговое руководство. Сохранение действие состояния.For an example of saving state using a Bundle, refer to the Walkthrough - Saving the Activity state.

Ограничения пакетаBundle Limitations

Несмотря на то что OnSaveInstanceState позволяет легко для сохранения временных данных, он имеет некоторые ограничения:Although OnSaveInstanceState makes it easy to save transient data, it has some limitations:

  • Он не вызывается во всех случаях.It is not called in all cases. Например, нажатие клавиши Главная или обратно для выхода из действие не приведет к OnSaveInstanceState вызова.For example, pressing Home or Back to exit an Activity will not result in OnSaveInstanceState being called.

  • Переданный пакет OnSaveInstanceState не предназначена для больших объектов, таких как изображения.The bundle passed into OnSaveInstanceState is not designed for large objects, such as images. В случае больших объектов, сохранение объекта из OnRetainNonConfigurationInstance предпочтительнее, как описано ниже.In the case of large objects, saving the object from OnRetainNonConfigurationInstance is preferable, as discussed below.

  • Данные, сохраненные с помощью пакета сериализуется, что может привести к задержкам.Data saved by using the bundle is serialized, which can lead to delays.

Состояние пакета полезно для простых данных, который не использует много памяти, тогда как данные экземпляра не конфигурации полезна для более сложных данных, или данные, ресурсоемкость извлечения, например, вызов веб-службы или очень сложный запрос к базе данных.Bundle state is useful for simple data that doesn't use much memory, whereas non-configuration instance data is useful for more complex data, or data that is expensive to retrieve, such as from a web service call or a complicated database query. Данные экземпляра конфигурации не сохраняются в объекте, при необходимости.Non-configuration instance data gets saved in an object as needed. В следующем разделе описывается OnRetainNonConfigurationInstance как способ сохранения более сложными типами данных посредством изменения конфигурации.The next section introduces OnRetainNonConfigurationInstance as a way of preserving more complex data types through configuration changes.

Сохранение сложных данных.Persisting Complex Data

Помимо сохранения данных в пакете Android также поддерживает сохранение данных путем переопределения OnRetainNonConfigurationInstance и возвращение экземпляра Java.Lang.Object , содержащий данные для сохранения.In addition to persisting data in the bundle, Android also supports saving data by overriding OnRetainNonConfigurationInstance and returning an instance of a Java.Lang.Object that contains the data to persist. Существует два основных преимущества использования OnRetainNonConfigurationInstance для сохранения состояния:There are two primary benefits of using OnRetainNonConfigurationInstance to save state:

  • Объект, возвращенный из OnRetainNonConfigurationInstance выполняет также с типами данных более крупных и сложных, так как в памяти сохраняет этот объект.The object returned from OnRetainNonConfigurationInstance performs well with larger, more complex data types because memory retains this object.

  • OnRetainNonConfigurationInstance Метод, вызываемый по запросу и только в том случае, при необходимости.The OnRetainNonConfigurationInstance method is called on demand, and only when needed. Это наиболее экономичным решением, чем при использовании кэша вручную.This is more economical than using a manual cache.

С помощью OnRetainNonConfigurationInstance подходит для сценариев, где ресурсоемкость извлечения данных несколько раз, например вызовы веб-службы.Using OnRetainNonConfigurationInstance is suitable for scenarios where it is expensive to retrieve the data multiple times, such as in web service calls. Например рассмотрим следующий код, который выполняет поиск Twitter:For example, consider the following code that searches Twitter:

public class NonConfigInstanceActivity : ListActivity
{
  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);
    SearchTwitter ("xamarin");
  }

  public void SearchTwitter (string text)
  {
    string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);

    var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
    httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
  }

  void ResponseCallback (IAsyncResult ar)
  {
    var httpReq = (HttpWebRequest)ar.AsyncState;

    using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
      ParseResults (httpRes);
    }
  }

  void ParseResults (HttpWebResponse httpRes)
  {
    var s = httpRes.GetResponseStream ();
    var j = (JsonObject)JsonObject.Load (s);

    var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();

    RunOnUiThread (() => {
      PopulateTweetList (results);
    });
  }

  void PopulateTweetList (string[] results)
  {
    ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
  }
}

Этот код извлекает результаты из Интернета, в формате JSON, анализирует их и затем возвращает результаты в список, как показано на следующем снимке экрана:This code retrieves results from the web formatted as JSON, parses them, and then presents the results in a list, as shown in the following screenshot:

Результаты отображаются на экранеResults displayed on screen

При возникновении изменений в конфигурации — например, при повороте устройства - код повторяет этот процесс.When a configuration change occurs - for example, when a device is rotated - the code repeats the process. Для повторного использования изначально полученные результаты и не вызывают ошибочные, избыточных сетевых вызовов, можно использовать OnRetainNonconfigurationInstance для сохранения результатов, как показано ниже:To reuse the originally retrieved results and not cause needless, redundant network calls, we can use OnRetainNonconfigurationInstance to save the results, as shown below:

public class NonConfigInstanceActivity : ListActivity
{
  TweetListWrapper _savedInstance;

  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);

    var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;

    if (tweetsWrapper != null) {
      PopulateTweetList (tweetsWrapper.Tweets);
    } else {
      SearchTwitter ("xamarin");
    }

    public override Java.Lang.Object OnRetainNonConfigurationInstance ()
    {
      base.OnRetainNonConfigurationInstance ();
      return _savedInstance;
    }

    ...

    void PopulateTweetList (string[] results)
    {
      ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
      _savedInstance = new TweetListWrapper{Tweets=results};
    }
}

Теперь при повороте устройства исходные результаты извлекаются из LastNonConfiguartionInstance свойство.Now when the device is rotated, the original results are retrieved from the LastNonConfiguartionInstance property. В этом примере результаты состоят из string[] содержащий твитов.In this example, the results consist of a string[] containing tweets. Так как OnRetainNonConfigurationInstance требует Java.Lang.Object возвращаться, string[] упаковывается в классе, который наследуется от класса Java.Lang.Object, как показано ниже:Since OnRetainNonConfigurationInstance requires that a Java.Lang.Object be returned, the string[] is wrapped in a class that subclasses Java.Lang.Object, as shown below:

class TweetListWrapper : Java.Lang.Object
{
  public string[] Tweets { get; set; }
}

Например, при попытке использовать TextView как объект, возвращенный из OnRetainNonConfigurationInstance приводят к утечке действия, как показано в следующем коде:For example, attempting to use a TextView as the object returned from OnRetainNonConfigurationInstance will leak the Activity, as illustrated by the code below:

TextView _textView;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  var tv = LastNonConfigurationInstance as TextViewWrapper;

  if(tv != null) {
    _textView = tv;
    var parent = _textView.Parent as FrameLayout;
    parent.RemoveView(_textView);
  } else {
    _textView = new TextView (this);
    _textView.Text = "This will leak.";
  }

  SetContentView (_textView);
}

public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
  base.OnRetainNonConfigurationInstance ();
  return _textView;
}

В этом разделе мы показали, как для сохранения данных простого конечного с Bundle, и сохранять более сложные типы данных с помощью OnRetainNonConfigurationInstance.In this section, we learned how to preserve simple state data with the Bundle, and persist more complex data types with OnRetainNonConfigurationInstance.

СводкаSummary

Жизненный цикл действия Android предоставляет мощную платформу для управления состоянием действий в приложении, но это может быть сложным для понимания и реализации.The Android activity lifecycle provides a powerful framework for state management of activities within an application but it can be tricky to understand and implement. В этой главе представлены различные состояния, которые действие может выполнить во время существования, а также методы жизненного цикла, связанные с ними.This chapter introduced the different states that an activity may go through during its lifetime, as well as the lifecycle methods that are associated with those states. Далее рекомендации указано о том, какого рода логики должно выполняться в каждом из этих методов.Next, guidance was provided as to what kind of logic should be performed in each of these methods.