Android: effacer la pile arrière


330

Dans Android, j'ai quelques activités, disons A, B, C.

Dans A, j'utilise ce code pour ouvrir B:

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

En B, j'utilise ce code pour ouvrir C:

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

Lorsque l'utilisateur appuie sur un bouton en C, je veux revenir à A et effacer la pile arrière (fermer à la fois B et C). Donc, lorsque l'utilisateur utilise le bouton de retour B et C ne s'affiche pas, j'ai essayé ce qui suit:

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

Mais B et C apparaissent toujours si j'utilise le bouton de retour lorsque je suis de retour dans l'activité A. Comment puis-je éviter cela?

Réponses:


438

Essayez d'ajouter FLAG_ACTIVITY_NEW_TASKcomme décrit dans les documents pour FLAG_ACTIVITY_CLEAR_TOP:

Ce mode de lancement peut également être utilisé à bon escient en conjonction avec FLAG_ACTIVITY_NEW_TASK: s'il est utilisé pour démarrer l'activité racine d'une tâche, il mettra au premier plan toute instance en cours d'exécution de cette tâche, puis l'effacera à son état racine. Cela est particulièrement utile, par exemple, lors du lancement d'une activité à partir du gestionnaire de notifications.

Donc, votre code à lancer Aserait:

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
Merci mais j'ai essayé ça. Toujours quand j'appuie sur le bouton de retour après qu'il montre à nouveau C. Que puis-je manquer?
Martin

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

8
ne fonctionne pas pour moi, mais appeler finish () sur l'activité source fait ce que je devais atteindre
2cupsOfTech

10
J'ai eu le même problème que cela ne fonctionnait pas. Ce qui m'a arrangé, c'est d'appeler finish () après avoir commencé la nouvelle activité
Arno

20
J'ai également ajouté une intention claire supplémentaire = nouvelle intention (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (intention); terminer();
Sam

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

8
Avec tout le respect pour le CLEAR_TOPdrapeau - cette combinaison est la SEULE qui a complètement effacé la pile entière et fait de la nouvelle activité la seule dans l'application. Je vous remercie!
Aviel Gross

8
Quelle est la différence entre cela et la réponse acceptée?
Yuri Heupa

7
Merci, la différence avec la réponse acceptée est qu'avec ce drapeau, nous n'avons pas besoin d'appeler activity.finish
Pablo Cegarra

1
FLAG_ACTIVITY_CLEAR_TASK a parfaitement fonctionné avec NEW_TASK
Shamsul Arefin Sajib

1
Ce devrait être la réponse acceptée. Merci beaucoup.
MD Danish Ansari

77

Qu'en est-il de l'ajout d'un fichier de manifestes pour une activité connexe:

android:noHistory="true"

à la définition d'activité de B et C? Ils ne seront pas ajoutés au backstack. Je ne sais pas si c'est ce que vous voulez.


3
Soyez très prudent lorsque vous utilisez ceci - Si vous utilisez la connexion avec FB ou tout autre type de fonctionnalité similaire
Skynet

2
@Skynet Pourquoi? Quels sont les problèmes associés à cette opération?
Alfie Woodland

8
Lorsque vous passez le contrôle à FB pour la connexion à partir d'une page avec aucune histoire vraie, l'application FB ne sait plus où atterrir après avoir connecté l'utilisateur, dans mon cas, elle revenait à l'écran d'accueil du téléphone et j'ai presque perdu mon travail!
Skynet

Cela ne laisse pas une activité ajoutée au backstack .... ce n'est pas la bonne solution.
Tarun

Exactement ce que je recherche
Masum

63

Cela me dérange depuis longtemps. Enfin, je l'ai résolu en faisant ceci:

En fragment, utilisez:

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

Dans Activity, utilisez (ajoutez un indicateur d'intention de plus Intent.FLAG_ACTIVITY_CLEAR_TASKpar rapport au fragment):

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
Si vous utilisez des annotations
android

La solutioin d'activité a bien fonctionné pour moi. Bien que je pense qu'avec l'API 16, la solution de Daniel Schuler est plus facile.
PhilippS

Merci yosafatade, c'est ce qui me manquait!
Marty Miller

30
  1. Ajouter android:launchMode="singleTop"à l'élément d'activité dans votre manifeste pour l'activité A
  2. Ensuite, utilisez intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) et intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)au début de l'activité A

Cela signifie que lorsque l'activité A est lancée, toutes les tâches au-dessus d'elle sont effacées afin que A soit en haut. Une nouvelle pile arrière est créée avec A à la racine, et l'utilisation singleTopgarantit que vous ne lancez jamais A une seule fois (puisque A est maintenant en haut à cause de ..._CLEAR_TOP).


3
Oui. c'est ce que j'utilise maintenant, mais cela ne le fait pas. Toujours C apparaît lorsque je clique sur le bouton de retour.
Martin

Bizarrement, je l'ai utilisé dans un projet et cela fonctionne très bien ... appuyer en arrière me ramène à l'écran d'accueil. Peut-être que quelque chose d'autre se passe. Pourriez-vous poster votre manifeste?
Joseph Earl

J'ai redémarré l'émulateur et maintenant il semble fonctionner comme vous l'avez dit. Merci beaucoup pour votre aide!
Martin

singleTop ne devrait rien avoir à voir avec l'effacement de la pile.
stdout

29

À partir de l'API 16 (Jelly Bean), vous pouvez simplement appeler finishAffinity().

Maintenant, vous pouvez également appeler ActivityCompat.finishAffinity(Activity activity)avec la bibliothèque de compatibilité.

Veillez à définir taskAffinity dans le manifeste sur un nom de package unique pour ce groupe d'activités.

Voir pour plus d'informations:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


Vraiment une solution facile à utiliser si vous êtes déjà sur l'API 16. J'ai travaillé pour moi!
PhilippS

3
rappel: cela ne fonctionnera que pour les activités qui partagent la même tâche Nom de l'affinité
Ryan

cela ne fonctionne que si vous n'avez qu'une seule activité dans l'histoire.
arsent

17

Essayez d'utiliser

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

et pas

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

11

Si votre application a au minimum la version 16 de sdk, vous pouvez utiliser finishAffinity ()

Terminez cette activité ainsi que toutes les activités immédiatement en dessous dans la tâche en cours qui ont la même affinité.

Cela fonctionne pour moi Dans l'écran Top Payment, supprimez toutes les activités de back-stack,

 @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

Pour de futures recherches, essayez ce code.

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

Ces drapeaux ont finalement fonctionné pour moi. Ce que j'ai fait, c'est que j'ai commencé la même activité dans laquelle j'étais avec ces drapeaux et une sortie booléenne supplémentaire = true. Dans onCreate (), j'ai vérifié les paramètres de lancement pour EXIT et appelé finish () s'il était défini sur true. C'est beaucoup de tracas juste pour fermer votre propre application.
Janne Oksanen

8

Utilisez finishAffinity (); dans la tâche C lors du démarrage de la tâche A pour effacer les activités de backstack.


seule cette réponse fonctionne pour moi. Intent.FLAG_ACTIVITY_CLEAR_TOP et Intent.FLAG_ACTIVITY_NEW_TASK ne sont pas requis
nuttynibbles

7

Utilisez ce code pour démarrer une nouvelle activité et fermez ou détruisez toute autre pile d'activité ou pile arrière.

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

J'ai trouvé une solution intéressante qui pourrait aider. Je l'ai fait dans ma onBackPressed()méthode.

finishAffinity();
finish();

FinishAffinitysupprime la connexion de l'activité existante à sa pile. Et puis terminer vous aide à quitter cette activité. Ce qui finira par quitter l'application.


4

J'ai trouvé les réponses ici un peu trompeuses car le code de la question d'origine semble bien fonctionner pour moi?

Avec A étant l'activité racine, le démarrer à partir de B ou C uniquement avec FLAG_ACTIVITY_CLEAR_TOP supprime B et C de la pile arrière.


4

En kotlin, c'est presque la même chose que java. Uniquement | le symbole est remplacé par ou texte. Donc, c'est écrit comme-

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

3

J'ai essayé toutes les solutions et aucune ne fonctionnait individuellement pour moi. Ma solution est:

Déclarez Activity Acomme SingleTopen utilisant[android:launchMode="singleTop"] dans le manifeste Android.

Ajoutez maintenant les drapeaux suivants lors du lancement Ade n'importe où. Cela effacera la pile.

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_TOPne fonctionnera pas dans ce cas. Veuillez utiliser(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Pour plus de détails, consultez cette documentation.


2

Il me semble que vous devez commencer à Activity Cpartir à Activity Bl'aide startActivityForResult(). Lorsque vous cliquez sur un bouton Activity C, appelez setResult(RESULT_OK)et finish()ainsi Activity Cse termine. Dans Activity B, vous pourriez avoir la onActivityResult()réponse en vous invoquant également finish(), et vous seriez alors ramené à Activity A.


7
Oui, mais s'il y a 42 activités entre A et C, ce sera plutôt fastidieux. Le drapeau FLAG_ACTIVITY_CLEAR_TOP est censé faire directement ce que veut l'OP.
Guillaume Brunerie

Ce serait un moyen moins qu'optimal de réaliser ce que l'OP veut, et comme l'a dit @Guillaume, cela nécessiterait du code dans toutes les activités entre la racine et le haut de la pile.
Jake Basile

Dûment noté. Ce sont des drapeaux dont je dois me renseigner apparemment.
Maximus

1

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


1

Vous pouvez utiliser cet exemple pour appeler votre 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

pour moi l'ajout a Intent.FLAG_ACTIVITY_CLEAR_TASKrésolu le problème

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 avancé et réutilisable:

Vous pouvez définir le drapeau directement en utilisant la méthode setter. Dans Kotlin orest le remplacement de Java au niveau du bit ou |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Si vous l'utilisez plusieurs fois, créez une fonction d'extension d'intention

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

Vous pouvez ensuite appeler directement cette fonction avant de démarrer l'intention

intent.clearStack()

Si vous avez besoin d'ajouter des indicateurs supplémentaires dans d'autres situations, ajoutez un paramètre facultatif à la fonction d'extension.

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

0

De plus FLAG_ACTIVITY_CLEAR_TOP, vous pouvez également essayer d'ajouter Intent.FLAG_ACTIVITY_SINGLE_TOP:

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


Cela n'affecterait que l'activité en haut de la pile, pas sa racine.
Jake Basile

0

Le code donné fonctionne correctement. J'ai essayé dans l'exemple de cycle de vie d'application.

Je n'ai pas eu B et C dans la pile arrière après avoir commencé l'activité A avec l'indicateur FLAG_ACTIVITY_CLEAR_TOP


0

J'ai appelé activity_name.this.finish()après avoir commencé une nouvelle intention et cela a fonctionné pour moi.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Mais cela ne fonctionnera pas pour moi ... Je ne suggère pas cette solution, mais si la définition du drapeau ne fonctionne pas pour vous, vous pouvez essayer ceci .. Mais je recommande toujours de ne pas l'utiliser


0

Ajoutez AUCUN indicateur d'historique dans l'intention.

Dans l'activité B, démarrez l'activité C comme ci-dessous >>>>>>

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

0

En manifeste

android:launchMode="singleTask"

et

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

0

Soit ajoutez ceci à votre Activity BetActivity C

android:noHistory="true"

ou Override onBackPressedfonction pour éviter d'appuyer à nouveau avec a return.

@Override
public void onBackPressed() {
   return;
}

0

Utilisez la méthode setFlags () pour effacer l'arrière ouvert toutes les activités fermer et démarrer votre activité

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.