Qual é a diferença entre onPause () e onStop () das atividades do Android?

149

No documento do Android, aqui http://developer.android.com/reference/android/app/Activity.html , dizia 'Atividade entra em primeiro plano' será chamada onPause()e 'Atividade não está mais visível' será chamada onStop().

'Atividade entra em primeiro plano' não é o mesmo que 'Atividade não está mais visível'? Você pode me dizer qual é a diferença entre eles?

Michael
fonte
17
+1 para uma excelente pergunta. Além disso, uma pausedatividade está completamente ativa (mantém todas as informações de estado e membro e permanece anexada ao gerenciador de janelas). Uma stoppedatividade também retém todas as informações de estado e membro, mas não está mais anexada ao window manager.
ateiob 8/08/12

Respostas:

107

Não, se alguma atividade entrar em primeiro plano, isso não significa necessariamente que a outra atividade seja completamente invisível. Considere o seguinte caso:

Atividade com o tema Theme.Dialog

Aqui vemos as duas atividades ao mesmo tempo. A primeira atividade com os campos é obscurecida por outra atividade e o usuário não pode mais interagir com ela. No entanto, ainda é visível com todas as consequências resultantes.

Isso deixa uma dúvida sobre qual atividade é considerada totalmente opaca e cobre toda a tela e qual não é. Esta decisão é baseada na janela que contém a atividade. Se a janela tiver um sinalizador windowIsFloatingou windowIsTranslucent, considera-se que a atividade não torna invisível o material subjacente; caso contrário, ele faz e fará com onStop()que seja chamado. O código relevante pode ser encontrado em 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
fonte
10
+1 para uma ótima explicação, com foco na visibilidade parcial vs. total (in) visibilidade. Seria interessante saber a porcentagem limite da tela que faz o Android decidir entre onPause()e onStop(). É 100%? Se apenas um pixel da atividade anterior estiver visível, ele ainda está onPause()?
ateiob 8/08/12
3
@ateiob Não é dito em nenhum lugar, mas acho que sim. No entanto, geralmente é óbvio, porque a maioria das atividades que não preenchem a tela inteira simplesmente usa um dos estilos fornecidos pelo sistema para diálogos.
Malcolm
1
Estranho, mas no meu aplicativo onPause()não é chamado quando uma caixa de diálogo é exibida. onPause()só é chamado quando pressiono o botão home . Como isso é possível?
precisa saber é
Essa deve ser a resposta correta. A propósito, o primeiro plano é um diálogo ou atividade?
GMsoF 5/09/12
3
@GMsoF Uma atividade. Esse é o ponto principal: nem toda caixa de diálogo é realmente uma caixa de diálogo. Você pode fazer uma atividade parecer uma caixa de diálogo, para que seja realmente menor que a tela inteira.
Malcolm
38

Se você ainda conseguir ver parte dela (o Activityprimeiro plano não ocupa a tela inteira ou é um pouco transparente), onPause()será chamado. Se você não conseguir ver nenhuma parte, onStop()será chamado.

Uma caixa de diálogo **, por exemplo, pode não cobrir todo o anterior Activity, e esse seria um momento para onPause()ser chamado.

** Não estou me referindo a um Diálogo Android aqui, mas a uma idéia conceitual de algo que aparece e oculta apenas parte da tela do usuário. Esta nota foi adicionada para esclarecer com base em um comentário de @GMsoF abaixo

nicholas.hauschild
fonte
33
NÃO. Isso é enganador. Uma caixa de diálogo mostrada não chama onPause () porque a caixa de diálogo usa o contexto da atividade atual, considere a atividade ativa.
GMsoF 5/09/12
6
@GMsoF Parece que quando eu disse caixa de diálogo, você pensou que eu quis dizer Dialog, como na classe Android. O que eu estava dizendo, porém, é algo que obscurece parcialmente o primeiro Activitya ilustrar a idéia de que todos os novos Activitynão precisam cobrir completamente o anterior.
Nicholas.hauschild
11

Estar em primeiro plano significa que a atividade tem foco de entrada. Por exemplo, uma atividade pode ser visível, mas parcialmente obscurecida por uma caixa de diálogo focada. Nesse caso, onPause()será chamado, mas não onStop(). Quando a caixa de diálogo desaparecer, o onResume()método da atividade será chamado (mas não onStart()).

Ted Hopp
fonte
5
A coisa do diálogo pode ser enganosa. Vamos exibir uma caixa de diálogo de aviso a partir do thread principal da interface do usuário desta atividade, onPause () não será chamado nesse caso. Somente se esse diálogo for exibido em outra Atividade ou outro aplicativo.
Sam003
1
@Zhisheng - concordo com o seu comentário. Eu estava apenas parafraseando o tópico do guia do Activites : " onPause()é chamado quando o dispositivo entra no modo de suspensão ou quando uma caixa de diálogo é exibida" . Como esse encadeamento deixa claro, porém, um diálogo não significa necessariamente que uma atividade está em pausa (embora seja para, digamos, uma atividade mostrada como um diálogo ).
Ted Hopp
9

Na prática , deve-se considerar a diferença entre “onPause ()” e “onPause () + onStop ()”.

Sempre que alguma nova atividade ocorre e ocupa algum espaço parcial da tela. Portanto, sua atividade em execução anterior ainda é visível até certo ponto. Nesse caso, a atividade em execução anterior não é enviada para Back Stack. Portanto, aqui apenas o método onPause () é chamado .

Por outro lado, se alguma nova atividade ocorrer e ocupar a tela inteira para que sua atividade em execução anterior desapareça. Nesse caso, sua atividade em execução anteriormente é movida para Back Stack. Aqui, onPause () + onStop () são chamados.

Para Resumos

onPause () - a tela é parcialmente coberta por outra nova atividade. A atividade não é movida para a pilha traseira.

onPause () + onStop () - a tela é totalmente coberta por outra nova atividade. A atividade é movida para a pilha traseira.

Saiba mais sobre- Back Stack .

Yash
fonte
0

Em palavras concisas:

onStop()do método de ciclo de vida da atividade anterior é chamado quando outra atividade é mostrada. Quando você tem o Diálogo no topo da atividade, ele onPause()é chamado.

Nota : Atividades são os componentes que preenchem sua tela inteira.

Nota : Os diálogos não são Atividade, pois não preenchem completamente a tela.

Uddhav Gautam
fonte
0

Enfrentei muitos problemas com os métodos onPause e onStop e, portanto, limparei três cenários que encontrei:
1. Quando você clica no botão do aplicativo recente, nenhum método de ciclo de vida é chamado, mas o onWindowFocusChanged (boolean hasFocus) é chamado com o valor hasFocus passou como falso. Na versão android antes das 5, o método onPause costumava ser chamado ao pressionar o botão do aplicativo recente.

2. Quando uma atividade pop-up aparece sobre sua atividade, como mencionado por Malcolm , o botão onPause é chamado. Se uma nova atividade que ocupa a tela inteira for chamada, o onStop será chamado na atividade anterior. A caixa de diálogo de permissão do Android também faz com que sua atividade seja chamada de Pausa.

3)Se o tempo limite da tela expirar em sua atividade, a onPause será chamada. Depois de algum tempo, se você não abrir a tela, o onStop será chamado.

Também uma coisa importante mencionada pelo ateiob que completa a resposta

Uma atividade em pausa está completamente ativa (mantém todas as informações de estado e membro e permanece anexada ao gerenciador de janelas). Uma atividade parada também retém todas as informações de estado e membro, mas não está mais anexada ao gerenciador de janelas


Espero que ajude.

royatirek
fonte
0

sempre que uma nova atividade inicia, a atividade anterior onPauseserá chamada de forma desafiadora em qualquer circunstância.

na verdade, haverá duas circunstâncias:

1 - uma parte da atividade anterior é visível ou a nova atividade é transparente: somente onPauseserá chamada.

2- a atividade anterior é completamente coberta por uma nova atividade: ambas onPausee onStopserão chamadas

---- Bom afirmar algumas notas:

NOTA 1: se uma caixa de diálogo iniciar em cima de uma atividade NENHUMA onPauseou onStopserá chamada.

NOTA 2: se for uma atividade cujo tema está definido como um diálogo, o comportamento será como uma atividade normal.

NOTA 3: aparentemente, uma caixa de diálogo do sistema, como a de permissão, já que o marshmallow causará onPause.

Amir Ziarati
fonte
-5

Sim, eu tento entender e posso explicar isso abaixo:

Existem 2 atividades: AtividadeA e AtividadeB

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

Aqui está a atividade B. Siga meu comentário no 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 isso seja claramente

Lê Quốc Tiến
fonte
sempre, tentar explicar essa sensação marcas
Alexander Zaldostanov