Android: ouvrir l'activité sans enregistrer dans la pile

94

J'ai 2 activités: principale et liste.

Depuis Main, vous pouvez ouvrir la liste; à partir de la liste, vous pouvez ouvrir Main.

Je voudrais que chaque ouverture de List ne soit pas enregistrée dans «l'histoire». Ainsi, le fait d'appuyer en arrière depuis Main ne peut pas revenir à la liste.

C'est possible?

realtebo
la source
11
Si «list» démarre «main», faites-le appeler finish()immédiatement après startActivity(...). De cette façon, si l'utilisateur appuie sur RETOUR depuis «principal», il n'y aura rien vers lequel revenir.
Squonk
ceci est pour la navigation dans les notifications, mais les concepts peuvent être applicables developer.android.com/guide/topics/ui/notifiers/...
Kevin Lee

Réponses:

159

Lorsque vous démarrez votre liste Activity, définissez ses Intentindicateurs comme ceci:

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

Le FLAG_ACTIVITY_NO_HISTORYdrapeau empêche l' Activityajout du nouveau à la pile d'historique.

NB: comme le souligne @Sam, vous pouvez utiliser à la i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);place. Il n'y a pas de différence fonctionnelle.

Eric
la source
2
Juste un petit commentaire sur cette méthode: celle-ci fonctionnera parfaitement s'il n'y a que 2 activités. Mais si la liste Activité est capable de lancer une autre activité (disons la troisième activité), un appui sur le bouton de retour dans la troisième activité reviendra à l'activité principale et non à la liste Activité
VinceFR
En effet. Malheureusement, il n'y a aucun moyen d'éviter cela. Il n'y a pas de Intentdrapeau qui déclare "ne fait qu'ajouter à l'histoire s'il ne revient pas à l' Activityorigine".
Eric
1
non mais le drapeau FLAG_ACTIVITY_NEW_TASK fera l'affaire, la liste Activité sera ajoutée à l'historique mais toujours en haut, donc un
appui
7
Y a-t-il une raison particulière pour laquelle vous avez utilisé setFlags()au getFlags()lieu de Intent.addFlags()?
Sam
1
@VinceFR c'est exactement ce que je veux! a -> b -> c et retour directement à c-
realtebo
90

Dans le fichier manifeste, ajoutez:

android:noHistory="true" 

à l'activité que vous ne souhaitez pas conserver sur la pile.

Marcin S.
la source
y a-t-il une différence par rapport au démarrage de l'activité avec l'indicateur no_history?
realtebo le
1
Comme vous l'avez dit dans votre question "chaque ouverture de liste NE SERA PAS enregistrée dans" l'historique "" Par conséquent, chaque fois que vous ouvrez à nouveau votre application, cela vous amènera à l'activité principale
Marcin S.
@MarcinS. lorsque l'application ne figure pas dans la liste des applications récentes, elle ne fonctionne pas. Pouvez-vous s'il vous plaît expliquer pourquoi cela se produit
Ajit Kumar Dubey
1
Alors, quelle est la différence entre ces 2 approches (manifeste et drapeau)?
pumbosha
L'approche @pumbosha Manifest laissera toujours l'activité hors de l'histoire. L'approche d'indicateur vous permet de contrôler ce comportement au moment de l'exécution.
John Crawford
27

Utilisez la nouvelle tâche avec la compensation. Cela a fonctionné dans mon cas lorsque les autres options n'ont pas fonctionné.

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

Effacez toute la pile d'historique et démarrez une nouvelle activité sur Android

Kalel Wade
la source
1
Ce serait génial, mais y a-t-il un moyen d'arrêter l'animation de «changement de tâche» du système? L'ajout de FLAG_ACTIVITY_NO_ANIMATION ne l'empêche malheureusement pas!
androidguy
cela a un impact sur la vitesse de l'application?
Acauã Pitta
23

Il semble que si vous appelez finish () sur votre activité juste après en avoir ouvert une autre, celle qui est terminée est supprimée de la pile.

par exemple:

Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
finish();
dac2009
la source
Si votre téléphone ne fonctionne pas si vite, vous verrez que l'activité précédente se déplace.
Nolan
@Nolan c'est seulement si vous terminez avant de commencer l'activité
Henrik Bøgelund Lavstsen
7

Dans mon cas particulier, cela FLAG_ACTIVITY_NO_HISTORYn'a pas fonctionné. Ni l'un ni l'autre n'ont fonctionné FLAG_ACTIVITY_NEW_TASKou FLAG_ACTIVITY_CLEAR_TASKseuls.

Cependant FLAG_ACTIVITY_NEW_TASKet FLAG_ACTIVITY_CLEAR_TASKensemble a fonctionné.

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

Je voulais juste ajouter un moyen de le faire à Kotlin:

val i = Intent(this, LogInActivity::class.java)
startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK))
Devin B
la source
2
Plus d'une façon Kotlin: Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) }.also { startActivity(it) }
4ndro1d
3

Réponse tardive, mais ajoute une certaine profondeur à d'autres réponses. Tout se résume à ce que vous voulez qu'il se passe avec les autres activités lancées à partir de cette activité

Option 1 - Cette seule activité ne devrait pas avoir d'historique d'activité d'appel

Alors faites simplement:

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

Option 2 - Toutes les activités commencées à partir de cette activité spécifique ne devraient pas avoir d'historique

Ajoutez ensuite le manifeste de l'activité appelante:

android:noHistory="true" 

Mais si vous souhaitez avoir un historique dans une nouvelle activité, vous devez supprimer manuellement l'indicateur:

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

J'espère que cela clarifie d'autres réponses :)

Miku
la source
2

Essayez FLAG_ACTIVITY_CLEAR_TOP si l'activité est déjà en cours d'exécution:

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
l'amour en direct
la source
-4

Ne pouvez-vous pas remplacer le bouton de retour sur l'activité particulière pour arrêter la fonctionnalité de «retour»?

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

        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Broak
la source
6
Ne fais pas ça. Il est acceptable d'intercepter BACK à des fins spécifiques, mais le faire uniquement pour consommer silencieusement la presse BACK et empêcher l'arrêt d'une opération Activityn'est pas une bonne pratique.
Squonk
1
D'accord tout à fait ^ juste une option.
Broak
1
Il y a OnBackPressedpour ça.
Fred