page.title=Воссоздание операции page.tags=жизненный цикл операции helpoutsWidget=true trainingnavtop=true @jd:body

Содержание этого урока

  1. Сохранение состояния операции
  2. Восстановление состояния операции

См. также:

Существуют ситуации, когда операция уничтожается в результате нормального поведения приложения. Например, это происходит, когда пользователь нажимает кнопку Назад или когда операция подает сигнал о своем уничтожении посредством вызова {@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()} следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии.

Более подробную информацию о воссоздании операции в связи с перезапуском во время исполнения (например при повороте экрана) можно найти в разделе Обработка изменений в режиме выполнения.