¿Cuál es la diferencia entre onPause () y onStop () de Android Activites?

149

Desde el documento de Android aquí http://developer.android.com/reference/android/app/Activity.html , decía 'La actividad entra en primer plano' llamará onPause()y 'La actividad ya no es visible' llamará onStop().

¿No es 'La actividad entra en primer plano' igual que 'La actividad ya no es visible'? ¿Me puede decir cuál es la diferencia entre ellos?

Miguel
fuente
17
+1 para una excelente pregunta. Además, una pausedactividad está completamente viva (mantiene toda la información del estado y de los miembros y permanece adjunta al administrador de ventanas). Una stoppedactividad también retiene toda la información del estado y de los miembros, pero ya no se adjunta a la window manager.
ateiob

Respuestas:

107

No, si alguna actividad entra en primer plano, eso no significa necesariamente que la otra actividad sea completamente invisible. Considere el siguiente caso:

Actividad con el tema Theme.Dialog

Aquí vemos ambas actividades al mismo tiempo. La primera actividad con los campos está oscurecida por otra actividad, y el usuario ya no puede interactuar con ella. Sin embargo, todavía es visible con todas las consecuencias resultantes.

Eso deja una pregunta sobre qué actividad se considera totalmente opaca y cubre toda la pantalla y cuál no. Esta decisión se basa en la ventana que contiene la actividad. Si la ventana tiene una bandera windowIsFloatingo windowIsTranslucent, entonces se considera que la actividad no hace que las cosas subyacentes sean invisibles, de lo contrario, sí lo hará y hará onStop()que se llame. El código relevante se puede encontrar en 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);
Malcolm
fuente
10
+1 para una gran explicación, centrándose en la visibilidad parcial frente a total (in). Sería interesante saber el porcentaje de umbral de la pantalla que hace que Android decida entre onPause()y onStop(). ¿Es 100%? Si solo se ve un píxel de la actividad anterior, ¿está quieto onPause()?
ateiob
3
@ateiob No se dice en ninguna parte, pero creo que sí. Sin embargo, generalmente es obvio porque la mayoría de las actividades que no ocupan toda la pantalla simplemente usan uno de los estilos proporcionados por el sistema para los diálogos.
Malcolm
1
Es extraño, pero en mi aplicación onPause()no se llama en absoluto cuando se muestra un cuadro de diálogo. onPause()solo se llama cuando presiono el botón de inicio . ¿Cómo es esto posible?
ateiob
Esta debería ser la respuesta correcta. Por cierto, ¿lo primero es un diálogo o actividad?
GMsoF
3
@GMsoF Una actividad. Ese es el punto principal: no todos los diálogos son en realidad diálogos. Puede hacer que una actividad parezca un diálogo, por lo que en realidad es más pequeña que toda la pantalla.
Malcolm
38

Si aún puede ver alguna parte de él ( Activityal ponerse en primer plano, o bien no ocupa toda la pantalla o es algo transparente), onPause()se llamará. Si no puede ver ninguna parte, onStop()se le llamará.

Un cuadro de diálogo **, por ejemplo, puede no cubrir todo el anterior Activity, y este sería un momento para onPause()ser llamado.

** No me estoy refiriendo a un Diálogo de Android aquí, sino a una idea conceptual de algo que aparece y solo oscurece parte de la pantalla del usuario. Esta nota se agregó para aclarar en base a un comentario de @GMsoF a continuación

nicholas.hauschild
fuente
33
NO. Esto es engañoso. Un cuadro de diálogo mostrado no llamará a onPause () porque el cuadro de diálogo usa el contexto de la actividad actual, considera la actividad viva.
GMsoF
66
@GMsoF Parece que cuando dije el diálogo, pensaste que quería decir Dialog, como en la clase de Android. Sin embargo, a lo que me estaba refiriendo es a algo que en parte oculta el primero Activitypara ilustrar la idea de que todas las novedades Activityno necesitan cubrir completamente el anterior.
nicholas.hauschild
11

Estar en primer plano significa que la actividad tiene un enfoque de entrada. Por ejemplo, una actividad puede ser visible pero parcialmente oscurecida por un diálogo que tiene el foco. En ese caso, onPause()se llamará, pero no onStop(). Cuando el diálogo desaparece, onResume()se llamará al método de la actividad (pero no onStart()).

Ted Hopp
fuente
55
Lo del diálogo podría ser engañoso. Vamos a abrir un cuadro de diálogo de advertencia desde el hilo principal de la interfaz de usuario de esta actividad, onPause () no se llamará en este caso. Solo si este cuadro de diálogo aparece desde otra Actividad u otra Aplicación.
Sam003
1
@Zhisheng - Estoy de acuerdo con tu comentario. Estaba parafraseando el tema de la guía Activites : " onPause()se llama cuando el dispositivo se va a dormir o cuando aparece un diálogo" . Sin embargo, como este hilo deja en claro, un diálogo no necesariamente significa que una actividad está en pausa (aunque sería para, por ejemplo, una actividad que se muestra como un diálogo ).
Ted Hopp
9

Prácticamente , uno debe considerar la diferencia entre "onPause ()" y "onPause () + onStop ()".

Cada vez que ocurre una nueva actividad y ocupa un espacio parcial de la pantalla. Por lo tanto, su actividad de ejecución anterior todavía es visible hasta cierto punto. En este caso, la actividad que se ejecutaba anteriormente no se empuja a Back Stack. Entonces, aquí solo se llama al método onPause () .

Por otro lado, si se produce alguna Actividad nueva y ocupa la pantalla completa para que desaparezca su actividad anterior. En este caso, su actividad anterior se mueve a Back Stack. Aquí se llama a onPause () + onStop ().

A los resúmenes

onPause () - La pantalla está parcialmente cubierta por otra actividad nueva. La actividad no se mueve a Back Stack.

onPause () + onStop () - La pantalla está completamente cubierta por otra actividad nueva. La actividad se mueve a Back Stack.

Conozca más sobre Back Stack .

Yash
fuente
0

En palabras concisas:

onStop()del método del ciclo de vida de la actividad anterior se invoca cuando se muestra otra actividad. Cuando tiene Diálogo en la parte superior de la actividad, onPause()se invoca.

Nota : Las actividades son aquellos componentes que llenan toda su pantalla.

Nota : Los diálogos no son actividad, ya que no llenan completamente la pantalla.

Uddhav Gautam
fuente
0

Enfrenté muchos problemas con los métodos onPause y onStop y, por lo tanto, eliminaré tres escenarios que encontré:
1. Cuando hace clic en el botón de la aplicación reciente, no se llama a ningún método del ciclo de vida, pero se llama a onWindowFocusChanged (boolean hasFocus) con el valor hasFocus Pasado como falso. En la versión de Android anterior a la 5, el método onPause solía ser llamado, al presionar el botón de la aplicación reciente.

2. Cuando aparece una actividad emergente como sobre su actividad, como lo menciona Malcolm , se llama al botón onPause. Si se llama a una nueva actividad que ocupa toda la pantalla, se llama a onStop en la actividad anterior. El diálogo de permiso de Android también hace que su actividad llame a onPause.

3)Si la pantalla agota su actividad, se llama a onPause. Después de algún tiempo, si no abre la pantalla, se llamará a onStop.

También una cosa importante mencionada por el ateiob que completa la respuesta

Una actividad pausada está completamente activa (mantiene toda la información del estado y de los miembros y permanece adjunta al administrador de ventanas). Una actividad detenida también retiene toda la información del estado y de los miembros, pero ya no está adjunta al administrador de ventanas


Espero eso ayude.

royatirek
fuente
0

siempre que comience una nueva ACTIVIDAD, la actividad anterior se onPausellamará definitivamente en cualquier circunstancia.

en realidad habrá dos circunstancias:

1- una parte de la actividad anterior es visible o la nueva actividad es transparente: solo onPause se llamará.

2- la actividad anterior está completamente cubierta por una nueva actividad: ambas onPausey onStopse llamarán

---- Es bueno decir algunas notas:

NOTA 1: si se inicia un diálogo sobre una actividad NINGUNA onPauseo onStopse llamará.

NOTA 2: si se trata de una actividad cuyo tema se establece en un cuadro de diálogo, el comportamiento será como una actividad normal.

NOTA 3: al parecer, un diálogo del sistema como el diálogo de permiso, ya que causará malvavisco onPause.

Amir Ziarati
fuente
-5

Sí, trato de entender y puedo explicar esto a continuación:

Hay 2 actividades: Actividad A y Actividad B

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;
    }
}

Aquí está la actividad B. Sigue mi comentario en código

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;
    }
}
}

Espero que esto sea claro

Lê Quốc Tiến
fuente
siempre, trata de explicar que tiene sentido
Alexander Zaldostanov