В чем разница между onPause () и onStop () Android Activites?

149

Из документа Android здесь 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 ниже

nicholas.hauschild
источник
33
NO. Это вводит в заблуждение. Показанное диалоговое окно не будет вызывать 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 (boolean hasFocus) со значением hasFocus прошло как ложное. В версии для Android до 5, метод onPause используется для вызова при нажатии кнопки недавнего приложения.

2. Когда над вашей активностью появляется всплывающее окно, похожее на действие, как упоминал Малкольм , вызывается кнопка onPause. Если вызывается новая активность, занимающая весь экран, то onStop вызывается для предыдущей активности. Диалог разрешений Android также заставляет вашу активность вызывать OnPause.

3.Если время ожидания вашего экрана истекло, вызывается onPause. Через некоторое время, если вы не откроете экран, будет вызван onStop.

Также одна важная вещь, упомянутая ateiob, которая завершает ответ

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


Надеюсь, поможет.

royatirek
источник
0

всякий раз, когда начинается новая ДЕЯТЕЛЬНОСТЬ, предыдущая деятельность onPauseбудет вызываться вызывающе при любых обстоятельствах.

на самом деле будет два обстоятельства:

1- часть предыдущего действия видима или новое действие прозрачно: только onPauseбудет вызвано.

2- предыдущая деятельность полностью покрыта новой деятельностью: и так onPauseи onStopбудет называться

---- Хорошо бы отметить некоторые заметки:

ПРИМЕЧАНИЕ 1: если диалог начинается поверх действия, ни один из onPauseили onStopне будет вызван.

ПРИМЕЧАНИЕ 2: если это Activity, темой которой является диалог, поведение будет таким же, как и обычное действие.

ПРИМЕЧАНИЕ 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;
    }
}
}

Надеюсь это понятно

Lé Quốc Tiến
источник
всегда, пытайтесь объяснить, что имеет смысл
Александр Залдостанов