Android: abra a atividade sem salvar na pilha

94

Tenho 2 atividades: Principal e Lista.

Em Principal, você pode abrir a Lista; em Lista, você pode abrir o Principal.

Eu gostaria que todas as aberturas de List não fossem salvas no 'histórico'. Portanto, pressionar de volta em Main não pode retornar para List.

É possível?

Realtebo
fonte
11
Se 'lista' começar 'principal', faça com que seja chamada finish()imediatamente depois startActivity(...). Dessa forma, se o usuário pressionar VOLTAR em 'principal', não haverá nada para onde voltar.
Squonk
isso é para navegação de notificação, mas os conceitos podem ser aplicáveis developer.android.com/guide/topics/ui/notifiers/…
Kevin Lee

Respostas:

159

Ao iniciar a sua lista Activity, defina seus Intentsinalizadores assim:

Intent i = new Intent(...); // Your list's Intent
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); // Adds the FLAG_ACTIVITY_NO_HISTORY flag
startActivity(i);

O FLAG_ACTIVITY_NO_HISTORYsinalizador impede que o novo Activityseja adicionado à pilha de histórico.

NB: Como @Sam aponta, você pode usar no i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);lugar. Não há diferença funcional.

Eric
fonte
2
Apenas um pequeno comentário sobre este método: este funcionará perfeitamente se houver apenas 2 atividades. Mas se a atividade da lista for capaz de lançar outra atividade (digamos, a terceira atividade), pressione o botão voltar na terceira atividade para retornar à atividade principal e não à lista Atividade
VinceFR
De fato. Infelizmente, não há como evitar isso. Não existe uma Intentbandeira que diga "só acrescenta à história se não regressar à Activityorigem".
Eric,
1
não, mas o sinalizador FLAG_ACTIVITY_NEW_TASK fará o trabalho, a atividade da lista será adicionada ao histórico, mas sempre no topo, portanto, um
toque
7
Existe algum motivo particular que você usou setFlags()com em getFlags()vez de Intent.addFlags()?
Sam,
1
@VinceFR é exatamente o que eu quero! a -> b -> c e retornar diretamente para c-
realtebo
89

No arquivo de manifesto, adicione:

android:noHistory="true" 

para a atividade que você não deseja manter na pilha.

Marcin S.
fonte
Há alguma diferença em iniciar a atividade com o sinalizador no_history?
realtebo
1
Como você disse em sua pergunta "todas as aberturas de lista NÃO são salvas no 'histórico'" Portanto, sempre que você abrir seu aplicativo novamente, isso o levará para a atividade principal
Marcin S.
@MarcinS. quando o aplicativo não está na lista de aplicativos recentes, ele não funciona. Você pode explicar por que isso está acontecendo
Ajit Kumar Dubey
1
Então, qual é a diferença entre essas 2 abordagens (manifesto e sinalizador)?
pumbosha
A abordagem do Manifesto @pumbosha sempre deixará a atividade fora da história. A abordagem de sinalização permite controlar esse comportamento em tempo de execução.
John Crawford
27

Use a nova tarefa com limpeza. Isso funcionou no meu caso, quando as outras opções não.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Limpe toda a pilha de histórico e inicie uma nova atividade no Android

Kalel Wade
fonte
1
Isso seria ótimo, mas há uma maneira de interromper a animação de "mudança de tarefa" do sistema? Adicionar FLAG_ACTIVITY_NO_ANIMATION não o impede, infelizmente!
androidguy
isso impacta na velocidade do aplicativo?
Acauã Pitta
23

Parece que, se você chamar finish () em sua atividade logo após abrir outra, aquela que foi concluída é removida da pilha.

por exemplo:

Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
finish();
dac2009
fonte
Se o seu telefone não for tão rápido, você verá que a atividade anterior está diminuindo.
Nolan
@Nolan, isso só se você terminar antes de iniciar a atividade
Henrik Bøgelund Lavstsen
7

No meu caso particular FLAG_ACTIVITY_NO_HISTORYnão funcionou. Nem trabalharam FLAG_ACTIVITY_NEW_TASKou FLAG_ACTIVITY_CLEAR_TASKsozinhos.

No entanto FLAG_ACTIVITY_NEW_TASKe FLAG_ACTIVITY_CLEAR_TASKjuntos funcionaram.

Intent intent = new Intent(FooActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Fred
fonte
3

Só queria adicionar uma maneira de fazer isso em Kotlin:

val i = Intent(this, LogInActivity::class.java)
startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK))
Devin B
fonte
2
Mais de uma maneira Kotlin: Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) }.also { startActivity(it) }
4ndro1d
3

Resposta tardia, mas acrescenta alguma profundidade a outras respostas. Tudo se resume ao que você deseja que aconteça com outras atividades iniciadas a partir dessa atividade

Opção 1 - Apenas esta atividade não deve ter histórico de atividade de chamada

Depois é só fazer:

Intent i = new Intent(...);
i.addFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

Opção 2 - Todas as atividades iniciadas a partir dessa atividade específica não devem ter histórico

Em seguida, adicione o manifesto da atividade de chamada:

android:noHistory="true" 

Mas se você quiser ter um histórico em uma nova atividade, deverá remover manualmente o sinalizador:

Intent i = new Intent(...);
i.removeFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

Espero que isso esclareça outras respostas :)

Miku
fonte
2

Experimente FLAG_ACTIVITY_CLEAR_TOP se a atividade já estiver em execução:

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
amor ao vivo
fonte
-4

Você não pode substituir o botão Voltar em uma atividade específica para interromper a funcionalidade de 'retorno'?

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {

        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Broak
fonte
6
Não faça isso. É aceitável interceptar o BACK para fins específicos, mas fazê-lo apenas para consumir a imprensa BACK silenciosamente e evitar o encerramento de um Activitynão é uma boa prática.
Squonk
1
Concordo inteiramente ^ apenas uma opção.
Broak em
1
Existe OnBackPressedpara isso.
Fred