Коли саме називаються onSaveInstanceState () та onRestoreInstanceState ()?


102

Наступний малюнок (від офіційного документа ) описує відомий життєвий цикл діяльності Android:

введіть тут опис зображення

З іншого боку, коли діяльність знищується системою (наприклад, тому, що потрібно відновити пам'ять), стан активності іноді автоматично зберігається та відновлюється за допомогою методів onSaveInstanceState()і onRestoreInstanceState(), як проілюстровано наступним малюнком (також від офіційного документа ):

введіть тут опис зображення

Я знаю, що onSaveInstanceState()це не завжди називається, коли діяльність збирається знищити. Наприклад, якщо він знищений через те, що користувач натиснув кнопку "назад", стан активності не зберігається. Але в тих випадках , коли стан буде збережено і відновлено, і onSaveInstanceState()/ onRestoreInstanceState()додзвонилися, коли саме вони називаються ?

Наприклад, згідно з наведеними вище цифрами, вони onRestoreInstanceState()можуть називатися до onStart(), або після, onStart()але до onResume(), або після onResume(). Так само існує кілька можливостей для onSaveInstanceState(). То коли ж їх точно називають?

В ідеалі я хотів би побачити комбіновану діаграму, що показує стан життєвого циклу активності та методи збереження / відновлення , якщо такі існують.


Отримав остаточну відповідь з офіційного документа Android, OnSaveInstanceState () викликається між onPause () та onStop ().
Ріші

1
@Rishi Чи можете ви надати посилання на цей документ?
Луїс Мендо


читати Зберегти стан своєї діяльності Параграф там
Ріші

я прав чи ні, будь ласка, уточнюйте
Rishi

Відповіді:


107

Відповідно до документації :

недійсний наRestoreInstanceState (Пакет збереженийInstanceState)

Цей метод називається між onStart()і onPostCreate(Bundle).

void onSaveInstanceState (Розшарування статі)

Якщо буде викликано, цей метод з’явиться після onStop () для програм, орієнтованих на платформи, починаючи з Build.VERSION_CODES.P. Для програм, орієнтованих на більш ранні версії платформи, цей метод буде діяти перед onStop (), і немає гарантій щодо того, чи відбудеться він до або після OnPause ().


1
Дякую. Чи можете ви надати посилання на документацію?
Луїс Мендо

Так само я не думаю, що між onStart () і onPostCreate () є щось інше, тому onRestoreInstanceState () добре визначений у ланцюжку.
Стів М

Дуже дякую. Це уточнює питання
Луїс Мендо

1
@SteveM "Немає гарантій щодо того, чи відбудеться це до або після onPause ()" Це означає, що якщо ми спробуємо отримати доступ до перегляду (щоб отримати певне значення для збереження, як індекс із перегляду списку), ми можемо зіткнутися з NullPointerExceptions?
Тіаго

3
Тоді, що рекомендується, зберегти структуру даних у onPause та відновити її в onResume замість OnSaveInstanceState та onRestoreInstanceState?
Gödel77

18

Відповідно до doc1 та doc2

onSaveInstanceState

До Honeycomb дії не вважалися порушеними до того моменту, коли вони були призупинені, це означає, що onSaveInstanceState () викликався безпосередньо перед onPause (). Починаючи з Honeycomb, однак, вважається, що діяльність може бути порушеною лише після їх зупинки, що означає, що тепер onSaveInstanceState () буде викликаний перед onStop (), а не безпосередньо перед onPause ().

onRestoreInstanceState

Цей метод викликається між onStart () і onPostCreate (Bundle), коли активність повторно ініціалізується з раніше збереженого стану


сподобалось, як ви описували сценарії для різних версій Android
Jimit Patel

14

Окрім вже опублікованих відповідей, в Android P введена тонка зміна, яка є:

void onSaveInstanceState (Розшарування статі)

Якщо викликається цей метод буде відбуватися ПІСЛЯ onStop() для додатків , орієнтованих на платформи , починаючи з P . Для програм, орієнтованих на більш ранні версії платформи, цей метод буде застосовуватися раніше, onStop()і немає гарантій щодо того, чи відбуватиметься він до або після onPause().

Джерело: док

Щодо того, чому ця зміна введена, ось відповідь:

... тож програма може безпечно виконувати транзакції з фрагментами onStop()і зможе зберегти стійкий стан пізніше.

Джерело: док


Привіт, чудовий коментар. Чи знаєте ви, як буде поводитись додаток, на який націлено P, але працює на нижній верхівці? Те саме, що націлювання на додатки на нижній api, або воно буде послідовним для api та зберігатиме поведінку "націлювання на api"?
Filipkowicz

@Filipkowicz, Do you know how will behave app that target P but runs on lower api?Поки додаток запускається скажімо M, версія Android, на якій цей пристрій не містить змін, введена в P, а це означає, що незалежно від того, ви вказали ціль, оскільки Pви не побачите різні для пристроїв, що попередньо P Сподіваюся, що це відповість на ваше запитання.
azizbekian

Сьогодні я відчуваю себе такою розслабленою, прочитавши цю відповідь, тому що я робила курс безкоштовного андроїда на Udacity, і вони все ще мають стару версію навчальних посібників, яка в уроці 5 зазначає, що методи onStop та onDestroy не повинні бути там відображається textView. Але я не знав, що це стосується старіших версій Android, і я запускав свою програму на андроїдний пиріг і отримував метод onStop у своєму textView. Дуже дякую. Нарешті почуваюся добре.
Сандху

6

Це додаткова інформація для OnSaveInstanceState (пакет)

від док

Не плутайте цей метод із зворотними викликами життєвого циклу діяльності, такими як onPause (), який завжди викликається, коли діяльність розміщується у фоновому режимі або на шляху до знищення, або onStop (), що викликається до знищення. Одним із прикладів виклику onPause () та onStop (), а не цей метод, є те, коли користувач повертається назад із активності B до активності A: немає потреби викликати OnSaveInstanceState (Bundle) на B, оскільки цей конкретний екземпляр ніколи не буде відновлений , тому система уникає його виклику. Приклад, коли onPause () викликається, а не onSaveInstanceState (Bundle), це коли активність B запускається перед активністю A: система може уникати виклику onSaveInstanceState (Bundle) щодо активності A, якщо вона не загинула протягом життя B, оскільки стан інтерфейсу користувача A залишиться недоторканим.

Тож це реалізація за замовчуванням для ..

Реалізація за замовчуванням дбає про більшу частину стану інтерфейсу користувача, зателефонувавши наSaveInstanceState () для кожного перегляду в ієрархії, що має ідентифікатор, та збереженням ідентифікації поточного зосередженого перегляду (усе це відновлюється реалізація за замовчуванням onRestoreInstanceState (Bundle)). Якщо ви скасуєте цей метод, щоб зберегти додаткову інформацію, не захоплену кожним окремим представленням, ви, ймовірно, захочете зателефонувати до реалізації за замовчуванням, інакше будьте готові самостійно зберегти весь стан кожного перегляду.


0
String activityState;
@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) {
     activityState = savedInstanceState.getString(STATE_KEY);
 } 

   setContentView(R.layout.main_activity);
   mTextView = (TextView) findViewById(R.id.text_view);
} 

// Цей зворотний виклик викликається лише тоді, коли є збережений екземпляр, раніше збережений за допомогою // onSaveInstanceState (). Ми відновлюємо деякий стан у onCreate (), тоді як тут необов'язково можемо відновити // інший стан, можливо, застосований після завершення onStart (). // Пакет збереженогоInstanceState такий же, як той, який використовується в onCreate ().

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) {
 mTextView.setText(savedInstanceState.getString(STATE_KEY));
  } 


// invoked when the activity may be temporarily destroyed, save the instance 
//state here 
//this method will be called before onstop

@Override 
 public void onSaveInstanceState(Bundle outState) {
    outState.putString(STATE_KEY, activityState);

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

Вибачте, як це відповідає на питання, коли саме називаються методи збереження / відновлення ?
Луїс Мендо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.