Android: limpe a pilha traseira


330

No Android, eu tenho algumas atividades, digamos A, B, C.

Em A, eu uso esse código para abrir B:

Intent intent = new Intent(this, B.class);
startActivity(intent);

Em B, eu uso esse código para abrir C:

Intent intent = new Intent(this, C.class);
startActivity(intent);

Quando o usuário toca em um botão em C, quero voltar para A e limpar a pilha de trás (feche B e C). Portanto, quando o usuário usar o botão voltar B e C não será exibido, tentei o seguinte:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

Mas B e C ainda estão aparecendo se eu usar o botão voltar quando volto à atividade A. Como posso evitar isso?

Respostas:


438

Tente adicionar FLAG_ACTIVITY_NEW_TASKconforme descrito nos documentos para FLAG_ACTIVITY_CLEAR_TOP:

Esse modo de inicialização também pode ser usado com bom efeito em conjunto com FLAG_ACTIVITY_NEW_TASK: se usado para iniciar a atividade raiz de uma tarefa, ele trará qualquer instância dessa tarefa em execução no momento para o primeiro plano e depois a limpará para o estado raiz. Isso é especialmente útil, por exemplo, ao iniciar uma atividade do gerenciador de notificações.

Portanto, seu código para iniciar Aseria:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.

28
Obrigado, mas eu tentei isso. Ainda assim, quando toco no botão Voltar, depois mostra C novamente. O que posso estar perdendo?
Martin

4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
precisa

8
não funciona para mim no entanto chamando acabamento () sobre a atividade fonte faz o que eu precisava para alcançar
2cupsOfTech

10
Eu tive o mesmo problema que isso não estava funcionando. Que fixa-lo para mim era chamar acabamento () depois de iniciar a nova atividade
Arno

20
Também adicionei mais uma intenção clara de intenção = nova intenção (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (intenção); terminar();
Sam

147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

8
Com todo o respeito à CLEAR_TOPbandeira - essa combinação é a ÚNICA que limpou completamente toda a pilha e tornou a nova atividade a única no aplicativo. Obrigado!
Aviel Gross 8/15

8
Qual é a diferença entre esta e a resposta aceita?
Yuri Heupa 24/09

7
Graças, a diferença com a resposta aceita é que com esta bandeira que não precisa activity.finish chamada
Pablo Cegarra

1
FLAG_ACTIVITY_CLEAR_TASK funcionou perfeitamente em conjunto com New_Task
Shamsul Arefin Sajib

1
Essa deve ser a resposta aceita. Muito obrigado.
MD Danish Ansari

77

Que tal adicionar no arquivo manifestos para atividades relacionadas:

android:noHistory="true"

para a definição de atividade de B e C? Eles não serão adicionados ao backstack. Não tenho certeza se é isso que você deseja.


3
Tenha muito cuidado ao usar esta - Se você estiver usando o login com FB ou qualquer tipo semelhante de funcionalidade
Skynet

2
@Skynet Why? Quais são os problemas associados a fazer isso?
Alfie Woodland #

8
Quando você passa o controle para o FB para o login a partir de uma página com nohistory como true, o aplicativo FB não agora para onde pousar após o login do usuário; no meu caso, ele estava retornando à tela inicial do telefone e eu quase perdi meu emprego!
Skynet

Isso não permite que uma atividade seja adicionada ao backstack .... essa não é a solução correta.
quer

Exatamente o que eu estou procurando
Masum

63

Isso me incomoda por um longo tempo. Finalmente, resolvi fazer isso:

No fragmento, use:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

Em Atividade, use (adicione mais um sinalizador de intenção Intent.FLAG_ACTIVITY_CLEAR_TASKcomparado ao fragmento):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

1
Se você estiver usando anotações do Android, precisará adicionar: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade

A solução de atividade funcionou bem para mim. Embora eu ache que com a API 16 a solução de Daniel Schuler é mais fácil.
precisa saber é o seguinte

Obrigado yosafatade, era isso que eu estava perdendo!
Marty Miller

30
  1. Adicione android:launchMode="singleTop"ao elemento de atividade no seu manifesto a Atividade A
  2. Em seguida, use intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) e intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)ao iniciar a Atividade A

Isso significa que, quando a Atividade A é iniciada, todas as tarefas sobre ela são limpas para que A seja a primeira. Uma nova pilha traseira é criada com A na raiz, e o uso singleTopgarante que você só inicie A uma vez (já que A está no topo devido a ..._CLEAR_TOP).


3
Sim. é isso que estou usando agora, mas isso não acontece. Ainda C aparece quando eu aperto o botão Voltar.
Martin Martin

Estranho, eu usei isso em um projeto e funciona bem ... pressionar para trás me leva à tela inicial. Talvez haja algo mais acontecendo. Você poderia postar seu manifesto?
31711 Joseph Earl

Eu reiniciei o emulador e agora parece estar funcionando exatamente como você disse. Muito obrigado por sua ajuda!
Martin Martin

singleTop não deve ter nada a ver com limpar a pilha.
stdout

29

A partir da API 16 (Jelly Bean), você pode simplesmente ligar finishAffinity().

Agora você também pode ligar ActivityCompat.finishAffinity(Activity activity)com a biblioteca de compatibilidade.

Certifique-se de definir taskAffinity no manifesto como um nome de pacote exclusivo para esse grupo de atividades.

Consulte para obter mais informações:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


Solução realmente útil e fácil, se você já conhece a API 16. Funcionou para mim!
precisa saber é o seguinte

3
lembrete: isto só irá funcionar para atividades em que compartilham o mesmo nome taskAffinity
Ryan

isso só funciona se você tiver apenas uma atividade na história.
arsent

17

Tente usar

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

e não

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

11

Se o seu aplicativo tiver uma versão mínima do sdk 16, você poderá usar finishAffinity ()

Conclua esta atividade e todas as atividades imediatamente abaixo dela na tarefa atual que possui a mesma afinidade.

Isso é bom para mim. Na tela Pagamento principal, remova todas as atividades de pilha traseira,

 @Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29



8

Para pesquisas futuras, tente este código.

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

Essas bandeiras finalmente funcionaram para mim. O que fiz foi iniciar a mesma atividade em que estava com esses sinalizadores e um EXIT = booleano extra. O em onCreate (), verifiquei os parâmetros de inicialização para EXIT e chamei de finish () se estiver definido como verdadeiro. Isso é muito complicado apenas para fechar seu próprio aplicativo.
Janne Oksanen

8

Use finishAffinity (); na tarefa C ao iniciar a tarefa A para limpar as atividades de backstack.


somente essa resposta funciona para mim. Intent.FLAG_ACTIVITY_CLEAR_TOP e Intent.FLAG_ACTIVITY_NEW_TASK não são necessários
nuttynibbles

7

Use este código para iniciar uma nova atividade e feche ou destrua todas as outras pilhas de atividades ou pilhas de volta.

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

5
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.

5

Encontrei uma solução interessante que pode ajudar. Eu fiz isso no meu onBackPressed()método.

finishAffinity();
finish();

FinishAffinityremove a conexão da atividade existente à sua pilha. E, em seguida, terminar ajuda a sair dessa atividade. O que acabará saindo do aplicativo.


4

Eu achei as respostas aqui um pouco enganadoras, porque o código na pergunta original parece funcionar bem para mim?

Como A é a atividade raiz, iniciá-la em B ou C somente com FLAG_ACTIVITY_CLEAR_TOP remove B e C da pilha traseira.


4

No kotlin, é quase o mesmo que o java. Apenas | símbolo é substituído por ou texto. Então, está escrito como-

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

Eu tentei todas as soluções e nenhuma funcionou individualmente para mim. Minha solução é:

Declarar Activity Acomo SingleTopusando [android:launchMode="singleTop"]no manifesto do Android.

Agora adicione os seguintes sinalizadores ao iniciar Ade qualquer lugar. Isso limpará a pilha.

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();

2

Intent.FLAG_ACTIVITY_CLEAR_TOPnão funcionará neste caso. Por favor, use(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Para mais detalhes, consulte esta documentação.


2

Parece-me que você precisa para começar Activity Ca partir Activity Busando startActivityForResult(). Quando você clica em um botão em Activity C, chamada setResult(RESULT_OK)e finish()assim Activity Cterminou. Em Activity B, você pode ter a onActivityResult()resposta também chamando finish()a si próprio e depois será levado de volta para Activity A.


7
Sim, mas se houver 42 atividades entre A e C, isso será bastante tedioso. O sinalizador FLAG_ACTIVITY_CLEAR_TOP deve fazer diretamente o que o OP deseja.
Guillume Brunerie

Essa seria uma maneira menos otimizada de alcançar o que o OP deseja e, como o @Guillaume disse, exigiria código em todas as atividades entre a raiz e o topo da pilha.
26411 Jake Basile

Devidamente anotado. Essas são bandeiras que eu preciso aprender aparentemente.
Maximus

1

logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Você pode usar este exemplo para chamar a sua Activity AdeActivity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);


1

para mim adicionando Intent.FLAG_ACTIVITY_CLEAR_TASKresolveu o problema

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();

1

Kotlin reutilizável avançado:

Você pode definir o sinalizador diretamente usando o método setter. No Kotlin oré o substituto para o Java bit a bit ou |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Se você usar isso mais de uma vez, crie uma função de extensão Intent

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Você pode chamar diretamente essa função antes de iniciar a intenção

intent.clearStack()

Se você precisar adicionar outros sinalizadores em outras situações, adicione um parâmetro opcional à função de extensão.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

0

Além disso FLAG_ACTIVITY_CLEAR_TOP, você pode tentar adicionar Intent.FLAG_ACTIVITY_SINGLE_TOPtambém:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


Isso afetaria apenas a atividade no topo da pilha, não a raiz dela.
26411 Jake Basile

0

O código fornecido funciona corretamente. Eu tentei na amostra do ciclo de vida do aplicativo.

Não tenho B e C na pilha de trás após iniciar a atividade A com o sinalizador FLAG_ACTIVITY_CLEAR_TOP


0

liguei activity_name.this.finish()depois de iniciar uma nova intenção e funcionou para mim.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Mas isso não funcionará para mim ... Eu não estou sugerindo esta solução para uso, mas se a configuração do sinalizador não funcionar para você, você pode tentar isso ... mas ainda assim eu recomendo não usá-lo


0

Adicionar NO Flag Flag na intenção.

Na atividade B, inicie a atividade C como abaixo >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();

0

Em manifesto

android:launchMode="singleTask"

e

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0

Adicione isso ao seu Activity BeActivity C

android:noHistory="true"

ou Override onBackPressedfunção para evitar pressionar novamente com a return.

@Override
public void onBackPressed() {
   return;
}

0

Use o método setFlags () para que o verso claro abra todas as atividades feche e inicie sua atividade

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.