Was ist der Unterschied zwischen onPause () und onStop () von Android Activites?

148

Aus dem Android-Dokument hier http://developer.android.com/reference/android/app/Activity.html geht hervor , dass "Aktivität tritt in den Vordergrund" aufgerufen onPause()wird und "Aktivität ist nicht mehr sichtbar" aufgerufen wird onStop().

Ist "Aktivität tritt nicht in den Vordergrund" nicht dasselbe wie "Aktivität ist nicht mehr sichtbar"? Können Sie mir bitte sagen, was der Unterschied zwischen ihnen ist?

Michael
quelle
17
+1 für eine ausgezeichnete Frage. Außerdem ist eine pausedAktivität vollständig aktiv (sie verwaltet alle Status- und Mitgliedsinformationen und bleibt mit dem Fenstermanager verbunden). Eine stoppedAktivität behält auch alle Status- und Mitgliedsinformationen bei, ist jedoch nicht mehr mit dem verbunden window manager.
Ateiob

Antworten:

107

Nein, wenn eine Aktivität in den Vordergrund tritt, bedeutet dies nicht unbedingt, dass die andere Aktivität vollständig unsichtbar ist. Betrachten Sie den folgenden Fall:

Aktivität mit dem Thema Theme.Dialog

Hier sehen wir beide Aktivitäten gleichzeitig. Die erste Aktivität mit den Feldern wird durch eine andere Aktivität verdeckt, und der Benutzer kann nicht mehr mit ihr interagieren. Es ist jedoch immer noch mit allen daraus resultierenden Konsequenzen sichtbar.

Es bleibt die Frage, welche Aktivität als vollständig undurchsichtig angesehen wird und den gesamten Bildschirm abdeckt und welche nicht. Diese Entscheidung basiert auf dem Fenster, das die Aktivität enthält. Wenn das Fenster ein Flag windowIsFloatingoder hat windowIsTranslucent, wird davon ausgegangen, dass die Aktivität das zugrunde liegende Material nicht unsichtbar macht, andernfalls wird und wird onStop()es aufgerufen. Den entsprechenden Code finden Sie in 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
quelle
10
+1 für eine großartige Erklärung, wobei der Schwerpunkt auf der teilweisen oder vollständigen (In-) Sichtbarkeit liegt. Es wäre interessant, den Schwellenprozentsatz des Bildschirms zu kennen, der Android dazu bringt, sich zwischen onPause()und zu entscheiden onStop(). Ist es 100%? Wenn nur ein Pixel aus der vorherigen Aktivität sichtbar ist, ist es immer noch onPause()?
Ateiob
3
@ateiob Es wird nirgendwo gesagt, aber ich denke schon. Dies ist jedoch normalerweise offensichtlich, da die meisten Aktivitäten, die nicht den gesamten Bildschirm ausfüllen, einfach einen der vom System bereitgestellten Stile für Dialoge verwenden.
Malcolm
1
Seltsam, aber in meiner Anwendung onPause()wird überhaupt nicht aufgerufen, wenn ein Dialog angezeigt wird. onPause()wird nur aufgerufen, wenn ich die Home- Taste drücke . Wie ist das möglich?
Ateiob
Dies sollte die richtige Antwort sein. Im Vordergrund steht übrigens ein Dialog oder eine Aktivität?
GMsoF
3
@ GMsoF Eine Aktivität. Das ist der Hauptpunkt: Nicht jeder Dialog ist tatsächlich ein Dialog. Sie können eine Aktivität wie einen Dialog aussehen lassen, sodass sie tatsächlich kleiner als der gesamte Bildschirm ist.
Malcolm
38

Wenn Sie immer noch einen Teil davon sehen können ( Activityder Vordergrund nimmt entweder nicht den gesamten Bildschirm ein oder ist etwas transparent), onPause()wird aufgerufen. Wenn Sie keinen Teil davon sehen können, onStop()wird aufgerufen.

Ein Dialog ** zum Beispiel deckt möglicherweise nicht den gesamten vorherigen ab Activity, und dies wäre eine Zeit onPause(), um aufgerufen zu werden.

** Ich beziehe mich hier nicht auf einen Android-Dialog, sondern auf eine konzeptionelle Idee von etwas, das auftaucht und nur einen Teil des Benutzerbildschirms verdeckt. Dieser Hinweis wurde hinzugefügt, um dies anhand eines Kommentars von @GMsoF unten zu verdeutlichen

nicholas.hauschild
quelle
33
NEIN. Das ist irreführend. Ein angezeigter Dialog ruft onPause () nicht auf, da der Dialog den Kontext der aktuellen Aktivität verwendet und die Aktivität als lebendig betrachtet.
GMsoF
6
@ GMsoF Es klingt so, als hätte ich Dialog gesagt, du hast gedacht, ich meinte Dialog, wie in der Android-Klasse. Was ich jedoch vorhatte, ist etwas, das das erste teilweise verdeckt Activity, um die Idee zu veranschaulichen, dass alle neuen Activitynicht das vorherige vollständig verdecken müssen.
nicholas.hauschild
11

Im Vordergrund zu stehen bedeutet, dass die Aktivität einen Eingabefokus hat. Beispielsweise kann eine Aktivität sichtbar sein, aber teilweise durch einen Dialog mit Fokus verdeckt werden. In diesem Fall onPause()wird aufgerufen, aber nicht onStop(). Wenn der Dialog ausgeblendet wird, wird die onResume()Methode der Aktivität aufgerufen (aber nicht onStart()).

Ted Hopp
quelle
5
Die Dialogsache könnte irreführend sein. Lassen Sie uns einen Warndialog aus dem Haupt-UI-Thread dieser Aktivität öffnen. OnPause () wird in diesem Fall nicht aufgerufen. Nur wenn dieser Dialog aus einer anderen Aktivität oder einer anderen App angezeigt wird.
Sam003
1
@ Zhisheng - Ich stimme Ihrem Kommentar zu. Ich habe gerade das Thema des Activites-Handbuchs umschrieben : " onPause()Wird aufgerufen, wenn das Gerät in den Ruhezustand wechselt oder wenn ein Dialogfeld angezeigt wird" . Wie dieser Thread jedoch deutlich macht, bedeutet ein Dialog nicht unbedingt , dass eine Aktivität angehalten wird (obwohl dies beispielsweise für eine Aktivität gilt, die als Dialog angezeigt wird ).
Ted Hopp
9

In der Praxis sollte man den Unterschied zwischen "onPause ()" und "onPause () + onStop ()" berücksichtigen.

Immer wenn eine neue Aktivität auftritt und einen Teil des Bildschirms einnimmt. Ihre zuvor ausgeführte Aktivität ist also bis zu einem gewissen Grad noch sichtbar. In diesem Fall wird die zuvor ausgeführte Aktivität nicht in den Back Stack verschoben. Hier wird also nur die Methode onPause () aufgerufen .

Auf der anderen Seite, wenn eine neue Aktivität auftritt und den Vollbildmodus einnimmt, sodass Ihre zuvor ausgeführte Aktivität verschwindet. In diesem Fall wird Ihre zuvor ausgeführte Aktivität in den Backstack verschoben. Hier werden onPause () + onStop () aufgerufen.

Zu Zusammenfassungen-

onPause () - Der Bildschirm wird teilweise von anderen neuen Aktivitäten abgedeckt. Die Aktivität wird nicht in den Backstack verschoben.

onPause () + onStop () - Der Bildschirm wird vollständig von anderen neuen Aktivitäten abgedeckt. Die Aktivität wird in den Backstack verschoben.

Erfahren Sie mehr über Back Stack .

Yash
quelle
0

In kurzen Worten:

onStop()der Lebenszyklusmethode der vorherigen Aktivität wird aufgerufen, wenn eine andere Aktivität angezeigt wird. Wenn Sie Dialog oben in der Aktivität haben, wird dort onPause()aufgerufen.

Hinweis : Aktivitäten sind diejenigen Komponenten, die Ihren gesamten Bildschirm ausfüllen.

Hinweis : Dialoge sind keine Aktivität, da sie den Bildschirm nicht vollständig ausfüllen.

Uddhav Gautam
quelle
0

Ich hatte viele Probleme mit den Methoden onPause und onStop und werde daher drei Szenarien löschen, auf die ich gestoßen bin:
1. Wenn Sie auf die Schaltfläche für die letzte App klicken, wird keine Lebenszyklusmethode aufgerufen, sondern onWindowFocusChanged (boolean hasFocus) mit dem Wert hasFocus als falsch bestanden. In der Android-Version vor 5 wurde die onPause-Methode beim Drücken der letzten App-Schaltfläche aufgerufen.

2. Wenn über Ihrer Aktivität eine Popup-ähnliche Aktivität angezeigt wird , wie von Malcolm erwähnt , wird die Schaltfläche onPause aufgerufen. Wenn eine neue Aktivität aufgerufen wird, die den gesamten Bildschirm einnimmt, wird onStop für die vorherige Aktivität aufgerufen. Der Android- Berechtigungsdialog bewirkt auch, dass Ihre Aktivität onPause aufruft.

3.Wenn der Bildschirm für Ihre Aktivität eine Zeitüberschreitung aufweist, wird onPause aufgerufen. Wenn Sie den Bildschirm nach einiger Zeit nicht öffnen, wird onStop aufgerufen.

Auch eine wichtige Sache, die vom Ateiob erwähnt wird und die Antwort vervollständigt

Eine angehaltene Aktivität ist vollständig aktiv (sie verwaltet alle Status- und Mitgliedsinformationen und bleibt dem Fenstermanager zugeordnet). Eine gestoppte Aktivität behält auch alle Status- und Mitgliedsinformationen bei, ist jedoch nicht mehr mit dem Fenstermanager verbunden


Ich hoffe es hilft.

Royatirek
quelle
0

Wenn eine neue AKTIVITÄT beginnt, wird die vorherige Aktivität unter onPausekeinen Umständen trotzig aufgerufen.

tatsächlich wird es zwei Umstände geben:

1- Ein Teil der vorherigen Aktivität ist sichtbar oder die neue Aktivität ist transparent: Nur onPausewird aufgerufen.

2- Die vorherige Aktivität wird vollständig durch eine neue Aktivität abgedeckt: beides onPauseund onStopwird aufgerufen

---- Gut, um einige Notizen zu machen:

HINWEIS 1: Wenn ein Dialogfeld über einer Aktivität gestartet wird, wird KEINE von onPauseoder onStopaufgerufen.

HINWEIS 2: Wenn es sich um eine Aktivität handelt, deren Thema auf einen Dialog festgelegt ist, entspricht das Verhalten einer normalen Aktivität.

HINWEIS 3: Anscheinend ein Systemdialog wie ein Berechtigungsdialog, da Marshmallow dies verursacht onPause.

Amir Ziarati
quelle
-5

Ja, ich versuche zu verstehen und ich kann dies unten erklären:

Es gibt 2 Aktivitäten: AktivitätA & AktivitätB

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

Hier ist Aktivität B. Folgen Sie meinem Kommentar im 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;
    }
}
}

Ich hoffe das ist klar

Lê Quốc Tiến
quelle
Versuchen Sie immer zu erklären, dass dies Sinn macht
Alexander Zaldostanov