Android: Unter welchen Umständen würde ein Dialogfeld dazu führen, dass onPause () aufgerufen wird?

78

Ein Ausschnitt aus dem Android- Aktivitätsdokument (scrollen Sie nach unten zur Zeile " Vordergrundlebensdauer ") lautet:

Eine Aktivität kann häufig in den Vordergrund und aus dem Vordergrund heraus wechseln. Sie wird beispielsweise onPause()aufgerufen, wenn das Gerät in den Ruhezustand wechselt oder wenn ein Dialogfeld angezeigt wird .

Ich verstehe das nicht ganz. Unter welchen Umständen sollte dies geschehen? Wird onPause()nur aufgerufen, wenn sich der Kontext des betreffenden Dialogfelds von der Aktivität unterscheidet, über der der Dialog angezeigt werden soll?

BEARBEITEN: Hinzufügen eines Codebeispiels, um meine Zweifel im Detail zu veranschaulichen

Sollte nach dem oben genannten Zitat aus dem Dokument die onPause()Methode meiner Aktivität aufgerufen werden, wenn das AlertDialog(oder nur das Dialog) im folgenden Code angezeigt wird? Sollte der Protokolleintrag "onPause aufgerufen" angezeigt werden, wenn der Dialog angezeigt wird?

Aber ich sehe das nicht. Und das sollte es auch nicht, wenn ich den Android-Lebenszyklus richtig verstanden habe! Also, worauf zeigt das Dokument dann?

public class LifeCycleTestActivity extends Activity {

    private static final String TAG = "LifeCycleTest";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick");

                AlertDialog dialog = new AlertDialog.Builder(LifeCycleTestActivity.this).create();
                 dialog.setMessage("You Clicked on the button");
                 dialog.setTitle("Dialog!");
                 dialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                 dialog.setCancelable(true);
                 dialog.show();


                /*
                Dialog dialog = new Dialog(LifeCycleTestActivity.this);
                 dialog.setTitle("Dialog!");
                 dialog.setCancelable(true);
                 dialog.show();
                */
            }
        });        
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause() called");
        super.onPause();

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume() called");
    }
}
neugieriger Techizen
quelle

Antworten:

187

onPause()wird aufgerufen, wenn sich Ihre Aktivität nicht mehr oben im Aktivitätsstapel befindet. Ein Dialog an sich ist keine Aktivität und ersetzt daher nicht die aktuelle Aktivität oben im Stapel. Daher wird nichts angehalten.

Ein Dialog (Kleinbuchstaben) muss jedoch nicht von einer Dialogklasse implementiert werden. Beispielsweise ist es nicht ungewöhnlich, eine Aktivität zu implementieren, deren Thema auf das eines Dialogfelds festgelegt ist. In diesem Fall führt das Anzeigen des Dialogfelds als Aktivität dazu, dass sich die neue Aktivität oben auf dem Stapel befindet und die zuvor vorhandene Aktivität angehalten wird.

Hackbod
quelle
8
Gute Antwort. Der "Dialog als Aktivität" war mir nicht eingefallen. Und die Argumentation, dass das onPause()nur aufgerufen wird, wenn sich der Dialog oben auf dem Stapel befindet - das erklärt auch, warum onPause()nicht aufgerufen wird, selbst wenn die Benachrichtigungsleiste nach unten gezogen wird, wodurch die Aktivität vollständig verdeckt wird.
neugieriger Techizen
2
@curioustechizen Hier gibt es so viele Feinheiten ... Dank Ihrer Frage (und der Antwort dieses erstaunlichen Profis aus dem Android-Team) konnte ich schnell verstehen, warum ich in meiner Anwendung genau das beobachte, was Sie beobachtet haben. +1.
Ateiob
1
@hackbod: Ein Systemdialog verursacht also onPause (). Ich sehe dies, während ich mir Marshmallow-Berechtigungs-bezogene Systemdialoge ansehe!
Abat
@abat Das liegt wahrscheinlich daran, dass der Berechtigungsdialog als Aktivität mit dem Thema eines Dialogs implementiert ist
neugieriger Techniker
13

Ich habe ziemlich viel Code mit Dialogen gemacht, einschließlich des von AlertDialogIhnen erwähnten, und ich habe auch versucht zu überprüfen, ob onPause()die Aktivität aufgerufen wird, wenn der Dialog erscheint, aber bisher meine Schlussfolgerung dass die Aktivität einfach ist läuft weiter und das onPause() heißt nicht .

Ich bin mir nicht sicher, ob es hilft, aber zumindest weißt du jetzt, dass es andere gibt, die erleben, was du erlebst :-)

Michell Bak
quelle
Nun, wenn ich den Lebenszyklus richtig verstehe, glaube ich, dass ein Dialog das NICHT auslösen darf onPause(). Das beobachtete Verhalten stimmt also mit dem überein, was erwartet wird. Es ist nur so, dass ich zufällig auf diese Information gestoßen bin, die ich zitiert und verlinkt habe. Und das führte mich auf den Weg der Verwirrung!
neugieriger Techizen
2

Es ist falsch, dass die Aktivität in der onPause-Phase nicht mehr oben auf dem Aktivitätsstapel bleibt.

Konditionieren Sie eine Aktivität auf OnPause-Status -

  • Aktivität teilweise sichtbar, zB Dialog über Aktivität.

  • Das Activity-Objekt bleibt im Speicher erhalten, verwaltet alle Status- und Mitgliedsinformationen und bleibt mit dem Fenstermanager verbunden.

    Wenn Sie beispielsweise die Home-Taste drücken, wird die Aktivität in onPause () ausgeführt. Immer noch oben auf dem Stapel.

In Abb. 1 wird Aktivität 3 zerstört und vom obersten Stapel entfernt

In Abb. 2 geht nun Aufgabe A in den Hintergrund, aber Activty X befindet sich immer noch oben auf dem Stapel. Wenn Sie die onPause () -Methode in diesem Status überschreiben

Geben Sie hier die Bildbeschreibung ein

Abbildung 1. Eine Darstellung, wie jede neue Aktivität in einer Aufgabe ein Element zum Backstack hinzufügt. Wenn der Benutzer die Zurück-Taste drückt, wird die aktuelle Aktivität zerstört und die vorherige Aktivität fortgesetzt.

Geben Sie hier die Bildbeschreibung ein

Abbildung 2. Zwei Aufgaben: Aufgabe B empfängt die Benutzerinteraktion im Vordergrund, während Aufgabe A im Hintergrund darauf wartet, wieder aufgenommen zu werden.

Yuvraj Kakkar
quelle
1
In dem von Ihnen erläuterten Szenario Activitybefindet sich das noch oben auf dem Stapel, aber die Aufgabe selbst ist in den Hintergrund getreten. Grundsätzlich interagiert der Benutzer nicht mehr mit Ihrem Activity- ein anderer Activity(entweder von Ihrer eigenen Aufgabe oder von einem anderen) ist in den Vordergrund getreten. Das versucht die akzeptierte Antwort zu erklären.
Neugieriger Bürger
0

Ich denke, ich erinnere mich, dass ich in einer früheren Version des Android-Lebenszyklus gelesen habe, dass onPause aufgerufen wurde, als keine der Aktivitäten angezeigt wurde. Wenn also ein Teil Ihrer Aktivität in einem Popup noch sichtbar ist, wird onPause nicht aufgerufen.

Vielleicht können einige andere Experten für dieses Verhalten bürgen?

FrinkTheBrave
quelle
Das bisschen darüber onPause(), aufgerufen zu werden, wenn keines von beiden Activityangezeigt wird - das ist im Allgemeinen wahr, aber nicht unbedingt. Wenn Sie beispielsweise die Benachrichtigungsleiste nach unten ziehen, sodass Ihre Aktivität vollständig verdeckt wird, onPause()wird sie immer noch nicht aufgerufen.
neugieriger Techizen
0

In meiner etwas seltsamen Erfahrung onResumewird mit angerufen, dialog.setCanceledOnTouchOutside(true);aber onPausenie angerufen.

Abgesehen davon denke ich, dass sich die Dokumentation auf Systemdialoge konzentrieren könnte (z. B. wenig Batterie).

Karl
quelle
0

@ Hackbot

onPause () wird aufgerufen, wenn sich Ihre Aktivität nicht mehr oben im Aktivitätsstapel befindet. Ein Dialog an sich ist keine Aktivität und ersetzt daher nicht die aktuelle> Aktivität oben im Stapel. Daher wird nichts angehalten.

alles hängt von der umsetzung ab ...

Was ist ein Dialog? ist ein Fenster , das von WindowManager /// zur Anzeige hinzugefügt wurde, sodass das angezeigte Fenster über allem liegt .... (Z-Reihenfolge)

Was Aktivität ist ... ist "Ding", das auch sein Fenster schafft ...

Wenn ein Dialogfeld angezeigt wird oder sein Fenster über einer vorhandenen Aktivität angezeigt wird, überschreibt es das Aktivitätsfenster teilweise, sodass vorhandene Aktivitäten in einen teilweise unsichtbaren Zustand versetzt werden und Sie von ActivityThread den Aufruf von onPause () erhalten .

aber um sicher zu sein, müssen wir hier auch einen Gedanken berücksichtigen ...

Der Status des Fensters ist ein eigenständiges Fenster , das oben angezeigt wird, oder ein untergeordnetes Fenster, und ein übergeordnetes Fenster ist ein Aktivitätsfenster. ...

also wenn wir es wissen

  • die Window.LayoutParams (FLAGS), die wir zum Hinzufügen verwenden
  • und was IBinder verwendet, damit das Fenster anzeigt

Wir werden zeigen, wie sich die Aktivität verhält, wenn Fenster übereinander angezeigt werden. Da jedes Fenster einen Rückruf hat , werden sie von Aktivität oder Dialog verwendet, um ihre zu verwalten.

beteiligte Komponenten:

  • android.os.IBinder

  • android.view.Window

  • android.view.Window.Callback

  • android.view.WindowManager

  • android.view.WindowManager.LayoutParams

  • android.view.Display

Übrigens:

Wenn Sie die Fenster auf dem Bildschirm kennen möchten [gilt nur für den Prozess, den Sie besitzen - da das Fenster zum Prozess gehört und diese in einer Sandbox gespeichert sind -, ist jeder Prozess eine separate JVM, die streng "ART" sagt], können Sie eine Antwort verwenden, siehe:

  • android.view.WindowManagerImpl
  • android.view.WindowManagerGlobal
ceph3us
quelle
-4

onPause()wird jedes Mal aufgerufen, wenn eine Aktivität in den Hintergrund tritt und die Dialogandere im ActivityVordergrund steht. Dies geschieht, um etwas, mit dem der Benutzer interagiert, erste Priorität einzuräumen. Beispiel: Angenommen, Sie befinden sich im Homescreen (was wiederum eine Aktivität ist) einer Anwendung. Der Homescreen befindet sich im foreground. und wenn Sie zum nächsten Bildschirm gehen durch eine Taste oder erscheint ein Dialog , der nächste screen/Activity/Dialogkommt foreGroundund homecreen geht in den Hintergrund, das bedeutet nur , Startbildschirm der onPause() Methode aufgerufen wurde.

ngesh
quelle
Nun, der Fall, in dem eine andere Aktivität in den Vordergrund tritt, ist offensichtlich. Ich bin verwirrt über die Behauptung des Dokuments, die onPause()aufgerufen wird, wenn ein Dialog angezeigt wird. Ich habe meine Frage mit Code bearbeitet, der erklärt, was meiner Meinung nach das Dokument behauptet, aber ich sehe kein Geschehen.
neugieriger Techizen
@ techie.curious..yeah vielleicht hast du recht. Es passiert nur beim Aktivitätsübergang und nicht, wenn ein Dialog erstellt wird. Ich habe es jetzt überprüft.
Ngesh