Quelle est la différence entre onPause () et onStop () d'Android Activites?

149

À partir de la documentation Android ici http://developer.android.com/reference/android/app/Activity.html , il est indiqué que «l'activité vient au premier plan» sera appelée onPause(), et «l'activité n'est plus visible» appellera onStop().

«L'activité au premier plan» n'est-elle pas la même chose que «L'activité n'est plus visible»? Pouvez-vous me dire quelle est la différence entre eux?

Michael
la source
17
+1 pour une excellente question. En outre, une pausedactivité est complètement vivante (elle conserve toutes les informations d'état et de membre et reste attachée au gestionnaire de fenêtres). Une stoppedactivité conserve également toutes les informations sur l'état et les membres, mais n'est plus attachée au window manager.
ateiob

Réponses:

107

Non, si une activité passe au premier plan, cela ne signifie pas nécessairement que l'autre activité est complètement invisible. Prenons le cas suivant:

Activité avec le thème Thème.

Ici, nous voyons les deux activités en même temps. La première activité avec les champs est masquée par une autre activité et l'utilisateur ne peut plus interagir avec elle. Cependant, il est toujours visible avec toutes les conséquences qui en résultent.

Cela laisse une question quelle activité est considérée comme totalement opaque et couvrant tout l'écran et laquelle ne l'est pas. Cette décision est basée sur la fenêtre contenant l'activité. Si la fenêtre a un drapeau windowIsFloatingou windowIsTranslucent, alors il est considéré que l'activité ne rend pas les éléments sous-jacents invisibles, sinon elle le fait et provoquera onStop()l'appel. Le code correspondant se trouve dans 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
la source
10
+1 pour une excellente explication, en se concentrant sur la visibilité partielle ou totale (in). Il serait intéressant de connaître le pourcentage seuil de l'écran qui permet à Android de choisir entre onPause()et onStop(). Est-ce à 100%? Si un seul pixel de l'activité précédente est visible, est-ce toujours onPause()?
ateiob
3
@ateiob Ce n'est dit nulle part, mais je pense que oui. Cependant, cela est généralement évident car la plupart des activités qui ne remplissent pas tout l'écran utilisent simplement l'un des styles fournis par le système pour les boîtes de dialogue.
Malcolm
1
Étrange, mais dans mon application onPause()n'est pas du tout appelée lorsqu'une boîte de dialogue est affichée. onPause()n'est appelé que lorsque j'appuie sur le bouton d' accueil . Comment est-ce possible?
ateiob
Cela devrait être la bonne réponse. Au fait, la chose au premier plan est un dialogue ou une activité?
GMsoF
3
@GMsoF Une activité. C'est le point principal: tous les dialogues ne sont pas en fait des dialogues. Vous pouvez faire en sorte qu'une activité ressemble à une boîte de dialogue, de sorte qu'elle soit en fait plus petite que la totalité de l'écran.
Malcolm
38

Si vous pouvez toujours voir une partie de celui-ci ( Activityvenir au premier plan n'occupe pas tout l'écran ou il est quelque peu transparent), onPause()sera appelé. Si vous ne voyez aucune partie de celui-ci, onStop()sera appelé.

Un dialogue **, par exemple, peut ne pas couvrir la totalité du précédent Activity, et ce serait le moment onPause()d'être appelé.

** Je ne parle pas ici d'une boîte de dialogue Android, mais plutôt d'une idée conceptuelle de quelque chose qui apparaît et n'obscurcit qu'une partie de l'écran de l'utilisateur. Cette note a été ajoutée pour clarifier sur la base d'un commentaire de @GMsoF ci-dessous

nicholas.hauschild
la source
33
NON. C'est trompeur. Une boîte de dialogue affichée n'appellera pas onPause () car la boîte de dialogue utilise le contexte de l'activité actuelle, considère l'activité active.
GMsoF
6
@GMsoF Cela ressemble à quand j'ai dit dialogue, vous pensiez que je voulais dire Dialog, comme dans la classe Android. Ce à quoi je voulais en venir, cependant, c'est quelque chose qui obscurcit en partie le premier Activitypour illustrer l'idée que toutes les nouveautés Activityn'ont pas besoin de couvrir complètement les précédentes.
nicholas.hauschild
11

Être au premier plan signifie que l'activité a un focus d'entrée. Par exemple, une activité peut être visible mais partiellement masquée par une boîte de dialogue qui a le focus. Dans ce cas, onPause()sera appelé, mais pas onStop(). Lorsque la boîte de dialogue disparaît, la onResume()méthode de l'activité sera appelée (mais pas onStart()).

Ted Hopp
la source
5
Le dialogue pourrait être trompeur. Une boîte de dialogue d'avertissement apparaît depuis le thread d'interface utilisateur principal de cette activité, onPause () ne sera pas appelé dans ce cas. Uniquement si cette boîte de dialogue apparaît à partir d'une autre activité ou d'une autre application.
Sam003
1
@Zhisheng - Je suis d'accord avec votre commentaire. Je paraphrasais juste le sujet du guide Activites : " onPause()est appelé lorsque l'appareil se met en veille ou lorsqu'une boîte de dialogue apparaît" . Comme ce fil l' indique clairement, cependant, une boîte de dialogue ne signifie pas nécessairement qu'une activité est mise en pause (bien que ce soit pour, par exemple, une activité présentée sous forme de boîte de dialogue ).
Ted Hopp
9

En pratique , il faut considérer la différence entre «onPause ()» et «onPause () + onStop ()».

Chaque fois qu'une nouvelle activité se produit et occupe une partie de l'espace de l'écran. Ainsi, votre activité précédente est toujours visible dans une certaine mesure. Dans ce cas, l'activité précédemment exécutée n'est pas poussée vers Back Stack. Donc, ici, seule la méthode onPause () est appelée .

D'autre part, si une nouvelle activité se produit et occupe le plein écran de sorte que votre activité précédente en cours disparaisse. Dans ce cas, votre activité précédente est déplacée vers Back Stack. Ici, onPause () + onStop () sont appelés.

Vers les résumés

onPause () - L'écran est partiellement couvert par d'autres nouvelles activités. L'activité n'est pas déplacée vers Back Stack.

onPause () + onStop () - L'écran est entièrement couvert par d'autres nouvelles activités. L'activité est déplacée vers Back Stack.

En savoir plus sur Back Stack .

Yash
la source
0

En termes concis:

onStop()de la méthode du cycle de vie de l'activité précédente est invoquée lorsqu'une autre activité est affichée. Lorsque vous avez Dialogue en tête de l'activité, il onPause()est appelé.

Remarque : les activités sont les composants qui remplissent tout votre écran.

Remarque : les dialogues ne sont pas des activités car ils ne remplissent pas complètement l'écran.

Uddhav Gautam
la source
0

J'ai rencontré de nombreux problèmes avec les méthodes onPause et onStop et je vais donc effacer trois scénarios que j'ai rencontrés:
1. Lorsque vous cliquez sur le bouton de l'application récente, aucune méthode de cycle de vie n'est appelée mais onWindowFocusChanged (booléen hasFocus) est appelé avec la valeur hasFocus passé comme faux. Dans la version Android antérieure à 5, méthode onPause utilisée pour être appelé, en appuyant sur le bouton de l'application récente.

2. Lorsqu'une activité de type pop-up apparaît au-dessus de votre activité, comme mentionné par Malcolm , le bouton onPause est appelé. Si une nouvelle activité qui occupe tout l'écran est appelée, onStop est appelé sur l'activité précédente. La boîte de dialogue d'autorisation Android provoque également l'appel de votre activité en pause.

3.Si l'écran expire pendant votre activité, onPause est appelé. Après un certain temps, si vous n'ouvrez pas l'écran, onStop sera appelé.

Aussi une chose importante mentionnée par l' ateiob qui complète la réponse

Une activité suspendue est complètement active (elle conserve toutes les informations d'état et de membre et reste attachée au gestionnaire de fenêtres). Une activité arrêtée conserve également toutes les informations d'état et de membre, mais n'est plus attachée au gestionnaire de fenêtres


J'espère que ça aide.

Royatirek
la source
0

chaque fois qu'une nouvelle ACTIVITÉ démarre, l'activité précédente onPausesera appelée avec défi en toutes circonstances.

en fait, il y aura deux circonstances:

1- une partie de l'activité précédente est visible ou la nouvelle activité est transparente: seule onPausesera appelée.

2- L'activité précédente est entièrement couverte par une nouvelle activité: les deux onPauseet onStopsera appelée

---- Bon pour énoncer quelques notes:

NOTE 1: si une boîte de dialogue démarre au-dessus d'une activité AUCUNE de onPauseou onStopne sera appelée.

NOTE 2: s'il s'agit d'une activité dont le thème est défini sur une boîte de dialogue, le comportement ressemblera à une activité normale.

REMARQUE 3: apparemment une boîte de dialogue système comme une boîte de dialogue d'autorisation car la guimauve provoquera onPause.

Amir Ziarati
la source
-5

Oui, j'essaie de comprendre et je peux l'expliquer ci-dessous:

Il y a 2 activités: ActivityA et 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;
    }
}

Voici l'activité B.Suivez mon commentaire dans le code

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

J'espère que c'est clairement

Lê Quốc Tiến
la source
toujours, essayez d'expliquer que cela a du sens
Alexander Zaldostanov