Яка різниця між OnPause () та OnStop () Android Activites?


149

З андроїд doc тут http://developer.android.com/reference/android/app/Activity.html сказано, що "Діяльність виходить на передній план" буде дзвонити onPause(), а "Активність більше не видно" onStop().

Чи не "Активність виходить на перший план" те саме, що "Активність більше не видно"? Скажіть, будь ласка, в чому різниця між ними?


17
+1 за відмінне запитання. Крім того, pausedдіяльність є повністю живою (вона зберігає всю інформацію про стан та членів і залишається приєднаною до менеджера вікон). stoppedАктивність також зберігає всі державні і член інформації, але більше не прикріплений до window manager.
ateiob

Відповіді:


107

Ні, якщо якась діяльність виходить на перший план, це не обов'язково означає, що інша діяльність є абсолютно невидимою. Розглянемо наступний випадок:

Активність із темою Theme.Dialog

Тут ми бачимо обидві дії одночасно. Перша активність із полями затьмарюється іншою діяльністю, і користувач більше не може з нею взаємодіяти. Однак це все одно видно з усіма наслідками, що випливають з цього.

Це залишає питання, яка діяльність вважається повністю непрозорою і охоплює весь екран, а яка ні. Це рішення базується на вікні, що містить активність. Якщо у вікні є прапор windowIsFloatingабо windowIsTranslucent, тоді вважається, що активність не робить базові речі невидимими, інакше це робить і викликає onStop()виклик. Відповідний код можна знайти в com.android.server.am.ActivityRecord:

fullscreen = ent != null && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsFloating, false)
        && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsTranslucent, false);

10
+1 для чудового пояснення, зосередившись на частковій та загальній видимості. Цікаво буде знати пороговий відсоток екрану, завдяки якому Android вирішує між onPause()та onStop(). Це 100%? Якщо видно лише один піксель з попередньої діяльності, чи все-таки це onPause()?
ateiob

3
@ateiob Ніде не сказано, але я так думаю. Однак зазвичай це очевидно, оскільки більшість видів діяльності, які не заповнюють весь екран, просто використовують один із запропонованих системою стилів для діалогів.
Малькольм

1
Дивно, але в моїй програмі onPause()взагалі не викликається, коли відображається діалогове вікно. onPause()викликається лише тоді, коли я натискаю кнопку додому . Як це можливо?
ateiob

Це має бути правильна відповідь. До речі, передній план - це діалог чи діяльність?
GMsoF

3
@GMsoF Активність. Це головний момент: не кожен діалог - це насправді діалог. Ви можете зробити діяльність схожою на діалог, тому вона насправді менша за весь екран.
Малькольм

38

Якщо ви все ще можете побачити будь-яку його частину ( Activityвихід на перший план або не займає весь екран, або він дещо прозорий), onPause()буде викликано. Якщо ви не бачите жодної його частини, onStop()будете викликані.

Наприклад, діалогове вікно ** може не охоплювати весь попередній Activity, і це був би час для onPause()виклику.

** Тут я не маю на увазі діалог Android, а концептуальна ідея того, що спливе і лише затьмарює частину екрану користувача. Ця примітка була додана для уточнення на основі коментаря від @GMsoF нижче


33
НЕМАЄ. Це вводить в оману. Діалогове вікно, яке не відображається, не викликає OnPause (), оскільки діалог використовує контекст поточної активності, вважайте активність активною.
GMsoF

6
@GMsoF Це здається, що коли я сказав діалог, ти думав, що я маю на увазі Dialog, як у класі Android. Що, на чому я потрапляв, - це те, що частково затьмарює перше, Activityщоб проілюструвати думку про те, що всім новим Activityне потрібно повністю приховувати попередні.
nicholas.hauschild

11

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


5
Діалог може бути оманливим. Давайте діалогове вікно попередження спливе з основного потоку інтерфейсу цієї активності, OnPause () не буде викликано в цьому випадку. Тільки якщо це діалогове вікно з’явиться з іншої діяльності чи іншого додатка.
Sam003

1
@Zhisheng - я згоден з вашим коментарем. Я щойно перефразовував тему керівництва Activites : " onPause()викликається, коли пристрій переходить у режим сну або коли з'являється діалогове вікно" . Оскільки цей потік стає зрозумілим, проте діалог не обов'язково означає, що діяльність призупинена (хоча це буде, скажімо, дія, показана як діалог ).
Тед Хопп

9

Практично слід враховувати різницю між "onPause ()" та "onPause () + onStop ()".

Щоразу, коли відбувається якась нова активність, яка займає деякий частковий простір Екрана. Тож ваша раніше запущена діяльність все ще видно деякою мірою. У цьому випадку раніше запущена діяльність не висувається на Back Stack. Отже, тут називається лише метод onPause () .

З іншого боку, якщо якась нова активність відбувається і займає весь екран, щоб ваша раніше запущена діяльність зникла. У цьому випадку ваша раніше запущена діяльність переміщується до Back Stack. Тут викликаються onPause () + onStop ().

До резюме-

onPause () - Екран частково охоплений іншою новою діяльністю. Діяльність не переміщена до Back Stack.

onPause () + onStop () - Екран повністю охоплений іншою новою діяльністю. Діяльність переміщується до Back Stack.

Дізнайтеся більше про - Back Stack .


0

Стислими словами:

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

Примітка . Діяльність - це ті компоненти, які заповнюють весь ваш екран.

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


0

Я зіткнувся з багатьма проблемами з методами onPause та onStop, і отже, я очищу три сценарії, на які я потрапив.
1. Коли ви натискаєте кнопку останнього додатка, не називається жоден метод життєвого циклу, але onWindowFocusChanged (булевий hasFocus) викликається зі значенням hasFocus передано як помилкове. У версії андроїда до 5, метод onPause, який використовується для виклику, натискання кнопки останнього додатка.

2. Коли над вашою діяльністю з'являється спливаюча активність, про яку згадує Малькольм , викликається кнопка onPause. Якщо викликається нова активність, яка займає весь екран, тоді onStop викликається попередньою діяльністю. Діалогове вікно дозволу Android також спричиняє вашу активізацію дзвінка на Пауза.

3.Якщо час екрану закінчується у вашій активності, виклик onPause. Через якийсь час, якщо ви не відкриєте екран, він буде викликаний.

Також одна важлива річ, згадана атейобом, що завершує відповідь

Призупинена активність є повністю живою (вона зберігає всю інформацію про стан та інформацію про учасників та залишається приєднаною до менеджера вікон). Припинена активність також зберігає всю інформацію про стан та членів, але більше не додається до вікна-менеджера


Сподіваюся, це допомагає.


0

всякий раз, коли починається нова ДІЯЛЬНІСТЬ, попередня діяльність onPauseбуде викликатися викликаючим при будь-яких обставинах.

насправді будуть дві обставини:

1- частина попередньої активності видима або нова активність прозора: тільки onPauseбуде викликано.

2 - попередня діяльність повністю охоплена новою діяльністю: і те, onPauseі інше onStopбуде називатися

---- Добре зазначити деякі примітки:

ПРИМІТКА 1: якщо діалогове вікно починається поверх активності, NONE onPauseабо onStopбуде викликана.

ПРИМІТКА 2: якщо це діяльність, тема якої встановлена ​​в діалоговому вікні, поведінка буде подібно до звичайної діяльності.

ПРИМІТКА 3. Очевидно, системний діалог, як діалог дозволів, оскільки зефір призведе до onPause.


-5

Так, я намагаюся зрозуміти це і можу пояснити це нижче:

Є 2 заходи: ActivityA та ActivityB

public class ActivityA extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
}

private void initialize() {
    Log.i("Activity A", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity A", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity A", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity A", "onResume");
}

@Override
protected void onPause() {
    super.onPause();
    Log.i("Activity A", "onPause");
}

@Override
protected void onStop() {
    super.onStop();
    Log.i("Activity A", "onStop");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i("Activity A", "onDestroy");
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        Intent activityB = new Intent(this, ActivityB.class);
        startActivity(activityB);
        break;
    default:
        break;
    }
}

Ось діяльність B. Слідкуйте за моїм коментарем у коді

public class ActivityB extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
    // if call finish() here, activityA will don't stop, just pause
    // Activity A will call onStop() when Activity B call onStart() method
    finish();
}

private void initialize() {
    Log.i("Activity B", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity B", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity B", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity B", "onResume");
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        finish();
        break;
    default:
        break;
    }
}
}

Я сподіваюся, що це однозначно


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