Є кілька сценаріїв, в яких ваша activity руйнується при нормальній поведінці додатків, наприклад, коли користувач натискає кнопку Back (Назад) або власні сигнали вашої activity самі її руйнують, викликаючи finish().
Система також може знищити вашу activity, якщо вона на даний час зупинена і не використовувалася протягом тривалого часу або передній план activity вимагає більше ресурсів, для чого система повинна закрити фонові процеси для відновлення пам'яті.
Коли ваша activity знищується, коли користувач натиснув Back або activity сама закінчує себе, то концепція системи даного екземпляру Activity йде назавжди, оскільки поведінка вказує, що activity більше не потрібна. Однак, якщо система руйнує activity із-за системних обмежень (а не із-за нормальної поведінки додатка), то хоча фактично екземпляр Activity йде, система запам'ятовує, що така activity існувала і, якщо користувач переходить назад до неї, то система створює новий екземпляр activity з використанням набору збереженої інформації, який описував стан activity, коли вона була зруйнована. Збережені дані, які система використовує для відновлення попереднього стану, називаються "стан екземпляра" і є колекцією пари ключ-значення, що зберігаються в об'єкті Bundle.
Увага: Ваша activity буде зруйнована і відтворена щоразу, коли користувач обертає екран. Коли екран змінює орієнтацію, то система знищує і відтворює передній план activity, тому що конфігурація екрану змінилася і вашій activity, можливо, треба буде завантажити альтернативні ресурси (наприклад, макет).
За замовчуванням, система використовує стан екземпляра Bundle, щоб зберегти інформацію про кожен об'єкт View в макеті activity (наприклад, текстове значення, введене в об'єкті EditText). Тому, якщо ваш екземпляр activity зруйнований і відтворений, то стан компоновки відновлений у своєму колишньому стані без необхідного вам коду. Тим не менш, ваша activity може мати більше інформації про стан, якщо хочете відновити, наприклад, змінних членів, які відстежують прогрес користувача в activity.
Примітка: Для того, щоб система Android відновила стан вигляду вашої activity, кожен вигляд повинен мати унікальний ідентифікатор, який додається до атрибута android:id.
Щоб зберегти додаткові дані про стан activity, необхідно перевизначити метод зворотного виклику onSaveInstanceState(). Система викликає цей метод, коли користувач залишає свою activity і передає його об'єкту Bundle, який буде збережений в тому випадку, коли ваша activity руйнується несподівано. Якщо система повинна відтворити екземпляр activity пізніше, то вона проходить той же самий об'єкт Bundle як до onRestoreInstanceState() так і до onCreate() методів.
Коли система починає зупиняти вашу activity, вона викликає onSaveInstanceState() (1), так що ви можете вказати додаткові дані про стан, які ви б хотіли зберегти в разі, коли екземпляр activity повинен бути відтворений. Якщо activity буде знищена і має бути відтворений той же екземпляр, то система передає дані стану, заданого в (1), як метод onCreate() (2) і метод onRestoreInstanceState() (3).
Збереження стану activity
Коли ваша activity починає зупинятися, система викликає onSaveInstanceState(), тому ваша activity може зберегти інформацію стану з колекцією пар ключ-значення. Реалізація за замовчуванням цього методу зберігає інформацію про стан вигляду ієрархії activity, такого, як текст у віджеті EditText або положення прокрутки в ListView.
Щоб зберегти додаткову інформацію про стан для вашої activity, ви повинні реалізувати onSaveInstanceState() і додати пари ключ-значення до об'єкта Bundle. Наприклад:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Збережіть нинішній стан гри користувача
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Завжди викликайте superclass, бо це зберігає стан вигляду ієрархії
super.onSaveInstanceState(savedInstanceState);
}
Увага: Завжди викликайте реалізацію суперкласу onSaveInstanceState(), бо та реалізація за замовчуванням може зберегти стан вигляду ієрархії.
Відновлення стану activity
Коли ваша activity відтворена після свого попереднього руйнування, то можна відновити збережений стан з Bundle, що система виконувала вашу свою activity. Обидва методи зворотніх викликів onCreate() і onRestoreInstanceState() отримують той же Bundle, що містить інформацію про стан екземпляра.
Тому що метод onCreate() викликається, коли система створює новий екземпляр вашої activity або відтворює попередній, то ви повинні перевірити, чи стан Bundle є недійсним, перш ніж намагатися прочитати його. Якщо це null, то система створює новий екземпляр activity, замість відновлення попереднього, який був зруйнований.
Приклад, як можете відновити деякі дані про стан в onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Завжди викликайте superclass першим
// Перевірте, чи буде відтворення раніше зруйнованого екземпляру
if (savedInstanceState != null) {
// Відновіть значення пам’яті зі збереженого стану
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Можливо, ініціалізація членів зі значеннями за замовчуваннями для нового екземпляру
}
...
}
Замість того, щоб відновити стан за допомогою onCreate(), можете вибрати для реалізації onRestoreInstanceState(), який викликає система після методу onStart(). Система викликає onRestoreInstanceState(), тільки якщо є збережений стан, щоб відновити, тому що вам не треба перевіряти, чи Bundle є null:
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Завжди викликайте superclass, бо так можете відновити вигляд ієрархії
super.onRestoreInstanceState(savedInstanceState);
// Відновіть членів стану зі збереженого екземпляру
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
Увага: Завжди викликайте реалізацію суперкласу onRestoreInstanceState(), бо так реалізація за замовчуванням може відновити стан вигляду ієрархії.
(Джерело: developer.android.com)