page.title=Воссоздание операции page.tags=жизненный цикл операции helpoutsWidget=true trainingnavtop=true @jd:body
Существуют ситуации, когда операция уничтожается в результате нормального поведения приложения. Например, это происходит, когда пользователь нажимает кнопку Назад или когда операция подает сигнал о своем уничтожении посредством вызова {@link android.app.Activity#finish()}. Система также может уничтожить операцию, если она остановлена и не используется в течение длительного времени, или если для выполнения операции на экране требуется больше системных ресурсов и системе нужно закрыть фоновые процессы для освобождения памяти.
Если операция уничтожается при нажатии пользователем кнопки Назад или завершении операции, система считает, что экземпляр {@link android.app.Activity} исчезает навсегда, так как такое поведение указывает, что операция больше не нужна. Однако если система уничтожает операцию в связи с системными ограничениями (а не в процессе обычной работы приложения), хотя фактический {@link android.app.Activity} экземпляр исчезает, система помнит о его существовании, и если пользователь вернется к нему, система создаст новый экземпляр действия, используя набор сохраненных данных, описывающий состояние операции на момент ее уничтожения. Сохраненные данные, используемые системой для восстановления предыдущего состояния, называются "состоянием экземпляра" и представляют собой набор пар "ключ-значение", хранящийся в объекте {@link android.os.Bundle}.
Внимание! Ваша операция будет уничтожаться и восстанавливаться каждый раз, когда пользователь вращает экран. При изменении ориентации экрана система уничтожает и заново создает активную операцию, поскольку конфигурация экрана меняется и операции может потребоваться загрузка альтернативных ресурсов (например нового макета).
По умолчанию система использует состояние экземпляра {@link android.os.Bundle} для сохранения информации о каждом объекте {@link android.view.View} в макете операции (например, о текстовом значении, введенном в объект {@link android.widget.EditText}). Таким образом, если экземпляр вашей операции уничтожается и воссоздается заново, происходит восстановление предыдущего состояния макета, и при этом вам не нужно добавлять в приложение дополнительный код. Однако операция может содержать больше информации о состоянии, чем вы хотите восстановить, например переменные, отслеживающие ход выполнения операции пользователем.
Примечание. Чтобы система Android могла восстановить состояние представлений операции, каждое представление должно иметь уникальный идентификатор, предоставляемый атрибутом {@code android:id}.
Для сохранения дополнительных данных о состоянии операции, необходимо заменить метод обратного вызова {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Система вызывает этот метод, когда пользователь покидает операцию, и передает ему объект {@link android.os.Bundle}, который будет сохранен в случае, если операция будет неожиданно уничтожена. Если системе нужно будет воссоздать экземпляр экземпляра операции, она передаст тот же объект {@link android.os.Bundle} методам {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} и {@link android.app.Activity#onCreate onCreate()}.
Рисунок 2. Когда система начинает останавливать операцию, она вызывает {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1), чтобы вы могли указать дополнительные данные состояния, которые нужно сохранить на случай необходимости воссоздания экземпляра {@link android.app.Activity}. Если операция будет уничтожена, и системе нужно будет воссоздать тот же экземпляр, она передаст данные состояния, определенные в (1), методам {@link android.app.Activity#onCreate onCreate()} (2) и {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (3).
Когда начинается остановка операции, система вызывает метод {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}, чтобы операция могла сохранить информацию о состоянии с помощью набора пар "ключ-значение". По умолчанию при реализации этого метода сохраняется информация о состоянии иерархии представления операции, например текст в виджете {@link android.widget.EditText} или положение экрана для {@link android.widget.ListView}.
Для сохранения дополнительной информации о состоянии операции необходимо реализовать {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} и добавить к объекту {@link android.os.Bundle} пары "ключ-значение". Например:
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); }
Внимание! Реализацию суперкласса {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии.
В случае воссоздания операции после предыдущего уничтожения сохраненное состояние можно восстановить из {@link android.os.Bundle}, куда система передает данные операции. Методы обратного вызова {@link android.app.Activity#onCreate onCreate()} и {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} получают один и тот же {@link android.os.Bundle}, содержащий информацию о состоянии экземпляра.
Поскольку метод {@link android.app.Activity#onCreate onCreate()} вызывается, если система создает новый экземпляр операции или восстанавливает предыдущий экземпляр, перед попыткой чтения необходимо убедиться, что {@link android.os.Bundle} имеет состояние null. В этом случае система создает новый экземпляр операции вместо восстановления ранее уничтоженного экземпляра.
Приведем пример восстановления некоторых данных о состоянии в {@link android.app.Activity#onCreate onCreate()}:
@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 } ... }
Вместо восстановления состояния в {@link android.app.Activity#onCreate onCreate()} вы можете реализовать метод {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, который система вызывает после метода {@link android.app.Activity#onStart()}. Система вызывает {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} только при наличии сохраненного состояния для восстановления, и поэтому вам не нужно проверять, имеет ли {@link android.os.Bundle} значение null:
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); }
Внимание! Реализацию суперкласса {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии.
Более подробную информацию о воссоздании операции в связи с перезапуском во время исполнения (например при повороте экрана) можно найти в разделе Обработка изменений в режиме выполнения.