Життєвий цикл активності Android - для чого всі ці методи?


419

Який життєвий цикл діяльності Android? Чому так багато подібних методів зондування ( onCreate(), onStart(), onResume()) викликається під час ініціалізації, і багато інших ( onPause(), onStop(), onDestroy()) викликається в кінці?

Коли називаються ці методи та як їх правильно використовувати?


17
Чому це питання було порушено так багато разів? Чому його не закрили?
Олександр Куляхтін

54
Навіщо закривати питання з великою кількістю відгуків? Stackoverflow має шкідливу звичку до цього.
Дік Лукас

12
Це питання у стилі вікі, і я вважаю, що його слід дозволити на сайті.
Матін Ульхак

2
@ Олександр Куляхтін - Чому закрити це питання? Натомість слід закрити свій обліковий запис, якщо ви не можете перетравити інформацію, яка міститься у відповідях для нових людей з Android. Це питання сповнене знань, і я збираюсь проголосувати це питання.
Переповнення стека

Бо коли ці методи називаються питаннями, що ви спробували?
Sreekanth Karumanaghat

Відповіді:


748

Перегляньте це в життєвому циклі діяльності (у розробників Android).

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

onCreate () :

Викликається, коли діяльність вперше створена. Тут ви повинні виконати всі свої звичайні статичні налаштування: створити представлення даних, прив’язати дані до списків тощо. Цей метод також надає вам пакет, що містить попередньо заморожений стан діяльності, якщо такий був. Завжди слідує onStart ().

onRestart () :

Викликається після припинення вашої діяльності, перш ніж її розпочати. Завжди дотримується OnStart ()

onStart () :

Викликається, коли діяльність стає видимою для користувача. Далі йде onResume (), якщо діяльність виходить на перший план.

onResume () :

Викликається, коли діяльність почне взаємодіяти з користувачем. На даний момент ваша активність знаходиться у верхній частині стека активності, і користувальницьке введення переходить до неї. Завжди слідує onPause ().

onPause () :

Називається частиною життєвого циклу діяльності, коли діяльність відходить на другий план, але ще не була вбита. Аналог onResume (). Коли активність B буде запущена перед активністю A, цей зворотний виклик буде викликаний на А. B не створюватиметься, поки A onPause () не повернеться, тому не забудьте тут нічого не робити.

onStop () :

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

onDestroy () :

Остаточний дзвінок, який ви отримуєте до знищення вашої діяльності. Це може статися або через те, що діяльність закінчується (хтось називає на ній закінчення (), або через те, що система тимчасово знищує цей екземпляр діяльності для економії місця. Ви можете розрізнити> два ці сценарії методом isFinishing ().

Коли Активність вперше завантажує події, називаються нижче:

onCreate()
onStart()
onResume()

Після натискання кнопки "Телефон " активність переходить на другий план і події нижче називаються:

onPause()
onStop()

Вийдіть із набору номера телефону і наступні події будуть викликані:

onRestart()
onStart()
onResume()

Коли ви натискаєте кнопку " НАЗАД" АБО спробуйте закінчити () активність, події називаються так:

onPause()
onStop()
onDestroy()

Діяльність держав

ОС Android використовує чергу пріоритетів, щоб допомогти в управлінні діями на пристрої. Залежно від стану, в якому знаходиться певна діяльність Android, йому буде призначений певний пріоритет в ОС. Ця система пріоритетів допомагає Android визначити види діяльності, які вже не використовуються, і дозволяє ОС відновлювати пам’ять та ресурси. Наступна діаграма ілюструє стани, через які діяльність може пройти протягом свого життя:

Ці стани можна розділити на три основні групи наступним чином:

Активні або бігові - Дії вважаються активними або запущеними, якщо вони стоять на передньому плані, також відомі як вершина стеку активності. Це вважається найвищою пріоритетністю в стеці Android Android, і внаслідок цього ОС буде вбита лише в надзвичайних ситуаціях, наприклад, якщо діяльність намагається використовувати більше пам’яті, ніж є на пристрої, оскільки це може спричинити використання інтерфейсу користувача стати безвідповідальним.

Призупинено - коли пристрій переходить у режим сну, або активність все ще помітна, але частково прихована новим, не повнорозмірним або прозорим заходом, діяльність вважається призупиненою. Призупинені дії все ще живі, тобто вони зберігають всю інформацію про стан та інформацію про членів та залишаються прив’язаними до менеджера вікон. Це вважається другою найвищою пріоритетною діяльністю в стеку Android Activity, і, як таке, ОС буде забита лише в тому випадку, якщо вбивство цієї активності задовольнить вимоги до ресурсів, необхідні для збереження активності / запущеної активності стабільною та чуйною.

Зупинено - Дії, які повністю затьмарені іншою діяльністю, вважаються припиненими або на задньому плані. Зупинені дії все ще намагаються зберегти інформацію про свої держави та членів якомога довше, але зупинені дії вважаються найнижчим пріоритетом трьох держав, і як така ОС буде вбивати діяльність у цій державі спочатку для задоволення потреб у ресурсах. діяльності з більш високим пріоритетом.

* Зразок діяльності для розуміння життєвого циклу **

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
    String tag = "LifeCycleEvents";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       Log.d(tag, "In the onCreate() event");
    }
    public void onStart()
    {
       super.onStart();
       Log.d(tag, "In the onStart() event");
    }
    public void onRestart()
    {
       super.onRestart();
       Log.d(tag, "In the onRestart() event");
    }
    public void onResume()
    {
       super.onResume();
       Log.d(tag, "In the onResume() event");
    }
    public void onPause()
    {
       super.onPause();
       Log.d(tag, "In the onPause() event");
    }
    public void onStop()
    {
       super.onStop();
       Log.d(tag, "In the onStop() event");
    }
    public void onDestroy()
    {
       super.onDestroy();
       Log.d(tag, "In the onDestroy() event");
    }
}

1
Тож якщо я правильно це зрозумів, onStop () завжди викликається після onPause ()?
Титуан де Байєль

4
НЕ завжди ", onStop (): Викликається, коли ви більше не бачите користувача"
Yaqub Ahmad

2
Чи є щось випадкове, що дзвонить перед onCreate?
NodeDad

6
Так, є - конструктор за замовчуванням (це той, який не має параметрів). Але він має дуже обмежене використання для дуже основних цілей ініціалізації. Зазвичай вам не слід його використовувати, якщо ви дійсно не знаєте, що робите. І навіть тоді вам слід подумати двічі, чи є кращий спосіб робити справи.
Mjoellnir

1
Я думаю, що це посилання може допомогти вам краще зрозуміти життєвий цикл діяльності. iphtechnologies.com/ розуміння-lifecycle-in-android-activity
Ashish Kumar Mishra

162

Діяльність має шість станів

  • Створено
  • Почав
  • Відновлено
  • Призупинено
  • Зупинився
  • Знищено

Життєвий цикл діяльності має сім методів

  • onCreate()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onRestart()
  • onDestroy()

життєвий цикл діяльності

Ситуації

  • Коли відкриєте додаток

    onCreate() --> onStart() -->  onResume()
  • Після натискання кнопки "Назад" та виходу з програми

    onPaused() -- > onStop() --> onDestory()
  • Коли натиснута домашня кнопка

    onPaused() --> onStop()
  • Після натискання кнопки додому, коли знову відкрийте додаток зі списку останніх завдань або натисніть на значок

    onRestart() --> onStart() --> onResume()
  • Коли відкрити додаток, ще одна програма з панелі сповіщень або відкрити налаштування

    onPaused() --> onStop()
  • Натиснута кнопка "Назад" з іншої програми чи налаштувань, які використовуються, може бачити наш додаток

    onRestart() --> onStart() --> onResume()
  • Коли на екрані відкриється будь-який діалог

    onPause()
  • Після відхилення діалогового вікна або кнопки повернення з діалогового вікна

    onResume()
  • Будь-який телефон дзвонить і користувачеві в додатку

    onPause() --> onResume() 
  • Коли користувач натиснув кнопку відповіді телефону

    onPause()
  • Після закінчення дзвінка

    onResume()
  • Коли екран телефону вимкнено

    onPaused() --> onStop()
  • Коли екран увімкнено знову

    onRestart() --> onStart() --> onResume()

6
"Коли на екрані відкриється будь-яке діалогове вікно, викликається onPause ()", не відповідає дійсності для діалогу попередження. Він називається лише тоді, коли діалогове вікно є самим діалоговим видом діяльності (для теми встановлено @android: style / Theme.Dialog).
gaurav jain

2
Цінна відповідь. Надішліть це в Google, щоб додати їх до документації. Я зберігаю вашу відповідь на документ Word, який потрібно зберегти!
likejudo

Я не розумію "Будь-який телефон дзвонить і користувачеві в додатку". Який саме сценарій? Моє перше було, якщо користувач у додатку, і телефон почне дзвонити, тоді він буде OnPause () -> onStop (), якщо на весь екран став дзвінок. Для заголовка вхідного дзвінка може бути просто OnResume -> onPause (), але я не впевнений у цьому. Яка ситуація у виклику onPause -> onResume? Чи в кінці дзвінка?
Сотті

Це те, що я шукав. Просто хотілося знати, куди мені покласти дзвінок на api.
Гейзенберг

Мені сподобалась ваша відповідь на основі сценарію .
кокабі

155

Вся плутанина викликана тим, що Google обрав неінтуїтивні імена замість чогось такого:

onCreateAndPrepareToDisplay()   [instead of onCreate() ]
onPrepareToDisplay()            [instead of onRestart() ]
onVisible()                     [instead of onStart() ]
onBeginInteraction()            [instead of onResume() ]
onPauseInteraction()            [instead of onPause() ]
onInvisible()                   [instead of onStop]
onDestroy()                     [no change] 

Діаграму діяльності можна інтерпретувати як:

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


1
Залежить. Якщо це не вирішить плутанину, довге ім’я не зашкодить. Наприклад: onRoutePresentationDisplayChanged () - це дуже багато функцій з Android SDK
Nilesh Pawar,

12
Я особисто не вважаю ваші імена надзвичайно інтуїтивно зрозумілими, а також з фрагментами це насправді не співвідноситься.
Мартін Маркончіні

9
Отримано. Більш корисна, ніж офіційна документація
bad_keypoints

3
Це чудовий пост. Одна проблема. Коли ви вводите способи життєвого циклу Andoid, щоб google це зображення відображалося над опцією пошуку (навіть не в режимі пошуку зображень) як відповідь на методи життєвого циклу Android. Невідомі (або ледачі, залежно від того, як ви на це дивитесь) можуть легко ввести в оману, якщо вони не перейдуть за посиланням StackOverflow, а не натискають на графічне зображення (ваше зображення).
Andrew S

1
Так. Це те, що я шукав. Хтось повинен написати книгу (чи документ?) З подібними матеріалами. onResume тощо не має сенсу.
Сувора Канчина

22

АНДРОІД ЖИТТЕ-ЦИКЛ

Існує сім методів управління життєвим циклом програми Android:


Відповідь, для чого всі ці методи:

Візьмемо простий сценарій, коли знання, в якому порядку викликаються ці методи, допоможе нам зрозуміти, чому вони використовуються.

  • Припустимо, ви використовуєте додаток для калькулятора. Для запуску програми послідовно викликаються три методи.

onCreate() - - -> - - ->onStart() onResume()

  • Коли я використовую програму калькулятора, раптом приходить дзвінок. Діяльність калькулятора переходить на другий план, а інша активність говорить. Справа з викликом виходить на перший план, і тепер два методи викликаються послідовно.

onPause() - - -> onStop()

  • Тепер скажіть, що я закінчу розмову по телефону, активність калькулятора виходить на перший план з фону, тому три методи викликаються послідовно.

onRestart() - - -> - - ->onStart() onResume()

  • Нарешті, скажіть, що я закінчив усі завдання з програми калькулятора, і я хочу вийти з програми. Далі два методи називаються послідовно.

onStop() - - -> onDestroy()


Існує чотири стани, діяльність яких може існувати:

  • Стартовий стан
  • Держава, що працює
  • Призупинена держава
  • Зупинений стан

Стартовий стан включає:

Створення нового процесу Linux, виділення нової пам’яті для нових об’єктів інтерфейсу та налаштування на весь екран. Тож тут бере участь більша частина роботи.

Стан, що працює, включає:

Це активність (стан), яка наразі на екрані. Сам цей стан обробляє такі речі, як набір тексту на екрані та торкання та натискання кнопок.

Паузальний стан передбачає:

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

Припинений стан включає:

Зупинену діяльність можна придбати на передній план, лише перезавантаживши її, а також її можна знищити в будь-який момент часу.

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


будь-який приклад для onPause для onResume ?
zeeali

14

Мені подобається це питання та відповіді на нього, але поки що немає покриття менш часто використовуваних зворотних зворотів, таких як onPostCreate () або onPostResume () . Стів Pomeroy спробував схему, що включає їх та як вони стосуються життєвого циклу Fragment Android за адресою https://github.com/xxv/android-lifecycle . Я переглянув велику діаграму Стіва, щоб включити лише частину " Діяльність" і відформатував її для роздруківки на одній сторінці. Я розмістив його як текстовий PDF на веб-сторінці https://github.com/code-read/android-lifecycle/blob/master/AndroidActivityLifecycle1.pdf та нижче - його зображення:

Життєвий цикл активності Android


8

На сторінці розробників Android,

onPause ():

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

onStop ():

Викликається, коли діяльність більше не відображається користувачеві, оскільки інша активність відновлена ​​та охоплює цю. Це може статися або тому, що починається нова діяльність, перед цим приводиться існуюча, або ця знищується. Після цього або onRestart (), якщо ця активність повертається для взаємодії з користувачем, або onDestroy (), якщо ця діяльність припиняється.

Тепер припустимо, що є три види діяльності, і ви переходите від A до B, тоді onPause A буде називатися зараз від B до C, тоді onPause of B і onStop of A буде викликано.

Призупинена активність отримує резюме, а зупиняється - відновлюється.

Коли ви телефонуєте this.finish() , буде викликано onPause-onStop-onDestroy. Головне пам’ятати: призупинені дії припиняються, а зупинена діяльність знищується, коли Android вимагає пам’яті для інших операцій.

Я сподіваюся, що це досить зрозуміло.


чи можемо ми вважати метод OnPause проміжним етапом між активністю, що починає втрачати фокус, і вона, нарешті, стає непомітною для користувача та методом Onstop, як коли діяльність стала повністю непомітною для користувача
Nav

Я думаю, що так і має бути.
Масіар

3
@Nav Припустимо, що є 3 заходи, і ви переходите від A до B, тоді onPause A буде називатися зараз від B до C, тоді onPause of B і onStop of A буде викликано.
MKJParekh

3

Додавання додаткової інформації зверху до високо оціненої відповіді (Додано додатковий розділ KILLABLE та наступний набір методів, які будуть викликані у життєвому циклі):

Джерело: developer.android.com

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

Зверніть увагу на " Killable стовпчик " у наведеній вище таблиці - для тих методів, які позначені як порушені, після цього методу повернення процесу, що розміщує активність, може бути вбита системою в будь-який час, не виконуючи інший рядок її коду.

Через це ви повинні використовувати onPause()метод для запису будь-яких постійних даних (наприклад, правки користувачів) у сховище. Крім того, метод onSaveInstanceState(Bundle)викликається перед тим, як розмістити активність у такому фоновому стані, що дозволяє зберегти будь-який динамічний стан екземпляра у вашій діяльності у заданий Bundle, щоб пізніше було отримано, onCreate(Bundle)якщо діяльність потрібно буде знову створити.

Зауважте, що важливо зберігати постійні дані onPause()замість того, onSaveInstanceState(Bundle)що останні не є частиною зворотного виклику життєвого циклу, тому він не буде викликаний у будь-якій ситуації, як описано в його документації.

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

onPostCreate(Bundle savedInstanceState)

Викликається після завершення запуску активності (після onStart()та виклику onRestoreInstanceState(Bundle)).

onPostResume()

Викликається, коли відновлення діяльності завершено (після того, onResume()як було викликано).

onSaveInstanceState(Bundle outState)

Викликається отримати стан екземпляра з активності перед вбивством, щоб стан можна було відновити в onCreate(Bundle)або onRestoreInstanceState(Bundle)(Пакет, заселений цим методом, буде передано обом).

onRestoreInstanceState(Bundle savedInstanceState)

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

Мій код програми, використовуючи всі ці методи:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText txtUserName;
    private EditText txtPassword;
    Button  loginButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("Ravi","Main OnCreate");
        txtUserName=(EditText) findViewById(R.id.username);
        txtPassword=(EditText) findViewById(R.id.password);
        loginButton =  (Button)  findViewById(R.id.login);
        loginButton.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        Log.d("Ravi", "Login processing initiated");
        Intent intent = new Intent(this,LoginActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("userName",txtUserName.getText().toString());
        bundle.putString("password",txtPassword.getText().toString());
        intent.putExtras(bundle);
        startActivityForResult(intent,1);
       // IntentFilter
    }
    public void onActivityResult(int requestCode, int resultCode, Intent resIntent){
        Log.d("Ravi back result:", "start");
        String result = resIntent.getStringExtra("result");
        Log.d("Ravi back result:", result);
        TextView txtView = (TextView)findViewById(R.id.txtView);
        txtView.setText(result);

        Intent sendIntent = new Intent();
        //sendIntent.setPackage("com.whatsapp");
        sendIntent.setAction(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_TEXT, "Message...");
        sendIntent.setType("text/plain");
        startActivity(sendIntent);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Ravi","Main Start");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Ravi","Main ReStart");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Ravi","Main Pause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Ravi","Main Resume");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Ravi","Main Stop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Ravi","Main OnDestroy");
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onPostCreate(savedInstanceState, persistentState);
        Log.d("Ravi","Main onPostCreate");
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.d("Ravi","Main PostResume");
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }
}

Активність входу:

public class LoginActivity extends AppCompatActivity {

    private TextView txtView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        txtView = (TextView) findViewById(R.id.Result);
        Log.d("Ravi","Login OnCreate");
        Bundle bundle = getIntent().getExtras();
        txtView.setText(bundle.getString("userName")+":"+bundle.getString("password"));
        //Intent  intent = new Intent(this,MainActivity.class);
        Intent  intent = new Intent();
        intent.putExtra("result","Success");
        setResult(1,intent);
       // finish();
    }
}

вихід: (перед паузою)

D/Ravi: Main OnCreate
D/Ravi: Main Start
D/Ravi: Main Resume
D/Ravi: Main PostResume

вихід: (Після відновлення після паузи)

D/Ravi: Main ReStart
D/Ravi: Main Start
D/Ravi: Main Resume
D/Ravi: Main PostResume

Зауважте, що onPostResume()викликається, навіть якщо він не цитується як метод життєвого циклу.


0

Я запускаю кілька журналів, як відповіді вище, і ось результат:

Початкова діяльність

On Activity Load (First Time)
————————————————————————————————————————————————
D/IndividualChatActivity: onCreate: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

Reload After BackPressed
————————————————————————————————————————————————
D/IndividualChatActivity: onCreate: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

OnMaximize(Circle Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onRestart: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

OnMaximize(Square Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onRestart: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

Припинення діяльності

On BackPressed
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop: 
D/IndividualChatActivity: onDestroy: 

OnMinimize (Circle Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onPause: 
D/IndividualChatActivity: onStop: 

OnMinimize (Square Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onPause: 
D/IndividualChatActivity: onStop: 

Going To Another Activity
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop: 

Close The App
————————————————————————————————————————————————
D/IndividualChatActivity: onDestroy: 

На мою особисту думку, потрібні лише два: onStart і onStop.

onResume, здається, є у кожному випадку повернення, а onPause у кожному випадку залишення (за винятком закриття програми).

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