Qual è la differenza tra onPause () e onStop () delle attività Android?


149

Dal documento Android qui http://developer.android.com/reference/android/app/Activity.html , diceva che "L'attività entra in primo piano" chiamerà onPause()e che "L'attività non è più visibile" chiamerà onStop().

"L'attività viene in primo piano" non è uguale a "L'attività non è più visibile"? Potete per favore dirmi qual è la differenza tra loro?


17
+1 per una domanda eccellente. Inoltre, pausedun'attività è completamente attiva (mantiene tutte le informazioni sullo stato e sui membri e rimane collegata al gestore finestre). Un'attività stoppedconserva anche tutte le informazioni sullo stato e sui membri, ma non è più associata a window manager.
ateiob,

Risposte:


107

No, se qualche attività viene messa in primo piano, ciò non significa necessariamente che l'altra attività sia completamente invisibile. Considera il caso seguente:

Attività con il tema Tema.Dialog

Qui vediamo entrambe le attività contemporaneamente. La prima attività con i campi è oscurata da un'altra attività e l'utente non può più interagire con essa. Tuttavia, è ancora visibile con tutte le conseguenze che ne derivano.

Ciò lascia una domanda quale attività è considerata completamente opaca e copre l'intero schermo e quali no. Questa decisione si basa sulla finestra contenente l'attività. Se la finestra ha un flag windowIsFloatingo windowIsTranslucent, allora si considera che l'attività non rende invisibili le cose sottostanti, altrimenti lo fa e farà onStop()chiamare. Il codice pertinente è disponibile 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);

10
+1 per un'ottima spiegazione, concentrandosi sulla visibilità parziale vs. totale (in). Sarebbe interessante conoscere la percentuale di soglia dello schermo che fa decidere ad Android tra onPause()e onStop(). È al 100%? Se è visibile solo un pixel dell'attività precedente, è ancora onPause()?
ateiob,

3
@ateiob Non si dice da nessuna parte, ma penso di si. Tuttavia, di solito è ovvio perché la maggior parte delle attività che non occupano l'intero schermo utilizzano semplicemente uno degli stili forniti dal sistema per le finestre di dialogo.
Malcolm,

1
Strano, ma nella mia applicazione onPause()non viene chiamato affatto quando viene visualizzata una finestra di dialogo. onPause()viene chiamato solo quando premo il tasto Home . Com'è possibile?
ateiob,

Questa dovrebbe essere la risposta corretta. A proposito, la cosa in primo piano è una finestra di dialogo o un'attività?
GMsoF,

3
@GMsoF Un'attività. Questo è il punto principale: non tutte le finestre di dialogo sono in realtà finestre di dialogo. Puoi rendere un'attività simile a una finestra di dialogo, quindi in realtà è più piccola dell'intero schermo.
Malcolm,

38

Se riesci ancora a vederne una parte ( Activityin primo piano o non occupa l'intero schermo, o è in qualche modo trasparente), onPause()verrà chiamato. Se non riesci a vederne alcuna parte, onStop()verrà chiamato.

Una finestra di dialogo **, ad esempio, potrebbe non coprire l'intero precedente Activity, e questo sarebbe un momento per onPause()essere chiamato.

** Non mi riferisco a una finestra di dialogo Android qui, piuttosto un'idea concettuale di qualcosa che si apre e oscura solo una parte dello schermo dell'utente. Questa nota è stata aggiunta per chiarire sulla base di un commento di @GMsoF di seguito


33
NO. Questo è fuorviante. Una finestra di dialogo mostrata non chiamerà onPause () perché la finestra di dialogo usa il contesto dell'attività corrente, considera l'attività viva.
GMsoF,

6
@GMsoF Sembra che quando ho detto dialoghi, pensavi che volessi dire Dialog, come nella classe Android. Quello a cui stavo arrivando, tuttavia, è qualcosa che oscura in parte il primo Activitya illustrare l'idea che tutti i nuovi Activitynon hanno bisogno di coprire completamente il precedente.
nicholas.hauschild,

11

Essere in primo piano significa che l'attività ha il focus di input. Ad esempio, un'attività può essere visibile ma parzialmente oscurata da una finestra di dialogo focalizzata. In tal caso, onPause()verrà chiamato, ma non onStop(). Quando la finestra di dialogo scompare, onResume()verrà chiamato il metodo dell'attività (ma non onStart()).


5
Il dialogo potrebbe essere fuorviante. Facciamo apparire una finestra di avviso dal thread dell'interfaccia utente principale di questa attività, in questo caso onPause () non verrà chiamato. Solo se questa finestra di dialogo viene visualizzata da altre attività o altre app.
Sam003,

1
@Zhisheng - Sono d'accordo con il tuo commento. Stavo solo parafrasando l'argomento della guida Activites : " onPause()viene chiamato quando il dispositivo va in modalità sospensione o quando viene visualizzata una finestra di dialogo" . Come chiarisce questo thread , tuttavia, una finestra di dialogo non significa necessariamente che un'attività sia messa in pausa (anche se sarebbe, per esempio, un'attività mostrata come finestra di dialogo ).
Ted Hopp,

9

In pratica , si dovrebbe considerare la differenza tra “onPause ()” e “onPause () + onStop ()”.

Ogni volta che si verifica una nuova attività e occupa uno spazio parziale dello schermo. Quindi l'attività in esecuzione in precedenza è ancora visibile in una certa misura. In questo caso, l'attività precedentemente in esecuzione non viene trasferita nello stack posteriore. Quindi, qui viene chiamato solo il metodo onPause () .

D'altra parte, se si verifica una nuova attività e occupa l'intero schermo in modo che l'attività precedentemente in esecuzione scompaia. In questo caso, l'attività precedentemente in esecuzione viene spostata nello stack posteriore. Qui vengono chiamati onPause () + onStop ().

Sommari

onPause () - Lo schermo è parzialmente coperto da altre nuove attività. L'attività non viene spostata nello stack posteriore.

onPause () + onStop () - Lo schermo è completamente coperto da altre nuove attività. L'attività viene spostata nello stack posteriore.

Scopri di più su Back Stack .


0

In parole sintetiche:

onStop()del metodo del ciclo di vita dell'attività precedente viene richiamato quando viene mostrata un'altra attività. Quando hai il dialogo in cima all'attività, onPause()viene invocato.

Nota : le attività sono quei componenti che riempiono l'intero schermo.

Nota : i dialoghi non sono attività in quanto non riempiono completamente lo schermo.


0

Ho riscontrato molti problemi con i metodi onPause e onStop e quindi deselezionerò tre scenari in cui mi sono imbattuto:
1. Quando fai clic sul pulsante app recente, non viene chiamato alcun metodo del ciclo di vita ma il metodo onWindowFocusChanged (hasFocus booleano) viene chiamato con valore hasFocus passato come falso. Nella versione Android precedente alla 5, il metodo onPause veniva chiamato, premendo il pulsante app recente.

2. Quando un'attività pop-up appare sopra la tua attività, come menzionato da Malcolm , viene chiamato il pulsante onPause. Se viene chiamata una nuova attività che occupa tutto lo schermo, viene chiamato onStop sull'attività precedente. La finestra di dialogo delle autorizzazioni Android provoca anche la chiamata della tua attività su Pausa.

3.Se lo schermo va in timeout sulla tua attività, viene chiamato onPause. Dopo qualche tempo se non aprirai lo schermo, verrà chiamato onStop.

Anche una cosa importante menzionata da ateiob che completa la risposta

Un'attività in pausa è completamente attiva (mantiene tutte le informazioni sullo stato e sui membri e rimane collegata al gestore finestre). Un'attività interrotta conserva anche tutte le informazioni sullo stato e sui membri, ma non è più collegata al gestore finestre


Spero che sia d'aiuto.


0

ogni volta che inizia una nuova ATTIVITÀ, l'attività precedente onPauseverrà chiamata con aria di sfida in qualsiasi circostanza.

in realtà ci saranno due circostanze:

1- una parte dell'attività precedente è visibile o la nuova attività è trasparente: solo onPause verrà chiamata solo.

2- l'attività precedente è completamente coperta da una nuova attività: entrambi onPausee onStopsaranno chiamati

---- Buono per indicare alcune note:

NOTA 1: se una finestra di dialogo inizia sopra un'attività NESSUNA onPauseo onStopverrà chiamata.

NOTA 2: se si tratta di un'attività il cui tema è impostato su una finestra di dialogo, il comportamento sarà proprio come un'attività normale.

NOTA 3: apparentemente una finestra di dialogo di sistema come la finestra di autorizzazione poiché causerà marshmallow onPause.


-5

Sì, cerco di capire e posso spiegarlo di seguito:

Ci sono 2 attività: Attività A e Attività 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;
    }
}

Ecco l'attività B. Segui il mio commento in codice

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

Spero sia chiaro


cerca sempre di spiegare che ha senso
Alexander Zaldostanov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.