Terminer toutes les activités précédentes


368

Mon application présente les écrans de flux suivants:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Maintenant, j'ai un log out bouton commun dans chaque écran

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Je veux que lorsque l'utilisateur clique sur le bouton de déconnexion (depuis n'importe quel écran), tous les écrans seront terminés et un nouvel écran Log ins'ouvrira.

J'ai presque tout essayé FLAG_ACTIVITYpour y parvenir. Je passe également par quelques réponses dans stackoverflow, mais ne pouvant pas résoudre le problème. Mon application est sur Android 1.6 donc ne peut pas utiliserFLAG_ACTIVITY_CLEAR_TASK

Existe-t-il un moyen de résoudre le problème?


Exécutez-vous vos activités imbriquées à l'aide de startActivityForResult?
woodshy

non.Toutes les activités sont démarrées avec startActivity.
Tanmay Mandal

J'utilise des activités imbriquées pendant que la morue exécute finishaffinitytask () dans une activité imbriquée. cela change-t-il le comportement? comme parfois j'obtiens un échec lors de la livraison du résultat ResultInfo lorsque finishaffinitytask s'exécute.
Ripal Tamboli

Veuillez vérifier cette réponse, cela vous aidera sûrement stackoverflow.com/a/25159180/2732632
Kimmi Dhingra

3
Android 21 a introduit Activity.finishAndRemoveTask ().
Joseph Johnson

Réponses:


543

Utilisation:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Cela effacera toutes les activités au-dessus de la maison.

En supposant que vous terminez l'écran de connexion lorsque l'utilisateur se connecte et que l'accueil est créé et ensuite tous les écrans de 1 à 5 en plus de celui-ci. Le code que j'ai publié vous ramènera à l'écran d'accueil en terminant toutes les autres activités. Vous pouvez ajouter un supplément dans l'intention et lire cela dans l'activité de l'écran d'accueil et le terminer également (peut-être relancer l'écran de connexion à partir de là ou quelque chose).

Je ne suis pas sûr mais vous pouvez également essayer de vous connecter avec ce drapeau. Je ne sais pas comment les activités seront ordonnées dans ce cas. Donc, je ne sais pas si cela effacera ceux sous l'écran sur lequel vous vous trouvez, y compris celui sur lequel vous vous trouvez actuellement, mais c'est certainement la voie à suivre.

J'espère que cela t'aides.


L'utilisateur affiche son premier écran comme écran d'accueil, c'est le principal problème.
Tanmay Mandal

ainsi que je l'ai ma réponse, vous devez revenir à l'écran d'accueil et terminer celui-ci. donc le processus appelle l'intention ci-dessus depuis n'importe quel écran. recevoir l'intention sur l'écran d'accueil et lancer instantanément une intention de connexion et terminer l'accueil après la méthode startActivity. vous pouvez également remplacer l'animation en attente par null pour in et out afin qu'elle ne montre pas la transition (je le fais parce qu'elle semble un peu plus rapide). donc cela devrait fonctionner correctement pour la chose dont vous avez besoin.
DArkO

10
Plutôt que de déclarer l'activité comme singleInstance, envisagez d'utiliser FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPcomme indicateurs pour l'intention. Cela terminera les activités intermédiaires et démarrera (ou ramènera au premier plan) l'activité souhaitée.
CommonsWare

13
@ CommonsWare L'ajout intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);à mon activité ne m'a pas aidé.Il n'a pas terminé les activités intermédiaires.Lorsque j'appuie sur l'écran de connexion, je peux voir les activités précédentes.Voici mon code Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
Tanmay Mandal

26
ce code efface uniquement la pile d'activité supérieure, pour effacer toutes les activités intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Ajay Venugopal

318

Vous pouvez essayer Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Il effacera totalement toutes les activités précédentes et commencera une nouvelle activité.


11
La bonne solution, mais seulement API 11+
riwnodennyk

J'ai fini par utiliser cet indicateur supplémentaire car il ne provoque pas de retard lors de l'affichage de l'activité principale (il ne le redémarrera pas, il est donc beaucoup plus rapide).
Maurizio

2
@riwnodennyk pourquoi API 11+?
Muhammad Babar

17
Utilisez IntentCompat.FLAG_ACTIVITY_CLEAR_TASK pour les versions antérieures à 11
Steven Pena

2
@ono Oui. Cela devrait être tout ce dont vous avez besoin. Assurez-vous que le mode de lancement de votre activité cible est défini comme "singleTask" dans le manifeste.
Steven Pena

137

Avant de lancer votre nouvelle activité, ajoutez simplement le code suivant:

finishAffinity();

Ou si vous souhaitez qu'il fonctionne dans les versions précédentes d'Android:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (this); appelle activity.finish () pour api <16. Donc ça ne marchera pas.
Aamir Abro

1
@Beto Caldas, j'ai moi-même confirmé le code source, cela ne fonctionnera pas pour l'API <16 comme l'a mentionné AamirAbro. Il ne fera que terminer l'activité que vous transmettez à l'API <16.
HendraWD

39

Lorsque l'utilisateur souhaite quitter toutes les activités ouvertes , il doit appuyer sur un bouton qui charge la première activité qui s'exécute au démarrage de votre application, effacer toutes les autres activités, puis terminer la dernière activité restante. Exécutez le code suivant lorsque l'utilisateur appuie sur le bouton Quitter. Dans mon cas, LoginActivityc'est la première activité de mon programme à exécuter.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Le code ci-dessus efface toutes les activités à l'exception de LoginActivity. Ensuite, mettez le code suivant dans le LoginActivity's onCreate(...), pour écouter quand LoginActivityest recréé et le signal' EXIT 'passé:

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Pourquoi est-il si difficile de créer un bouton de sortie dans Android?

Android s'efforce de vous décourager d'avoir un bouton "Quitter" dans votre application, car ils veulent que l'utilisateur ne se soucie jamais de savoir si les programmes qu'ils utilisent s'exécutent en arrière-plan ou non.

Les développeurs d'Android OS veulent que votre programme puisse survivre à un arrêt inattendu et à une mise hors tension du téléphone, et lorsque l'utilisateur redémarre le programme, il reprend là où il s'était arrêté. Ainsi, l'utilisateur peut recevoir un appel téléphonique pendant qu'il utilise votre application et ouvrir des cartes qui nécessitent que votre application soit libérée pour plus de ressources.

Lorsque l'utilisateur reprend votre application, il reprend là où il s'était arrêté sans interruption. Ce bouton de sortie usurpe le pouvoir du gestionnaire d'activité, ce qui peut potentiellement causer des problèmes avec le cycle de vie du programme Android géré automatiquement.


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Cela fonctionnera pour toutes les versions d'Android. Où IntentCompatla classe a été ajoutée dans la bibliothèque de support Android.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKn'est pas reconnu, utilisez Intentplutôt IntentCompat.
CoolMind

30

Utilisez ce qui suit pour l'activité

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

supprimer l'indicateur CLEAR_TASK pour l'utilisation du fragment.

J'espère que cela peut utiliser pour certaines personnes.


24

Je suppose que je suis en retard, mais il y a une réponse simple et courte. Il existe une méthode finishAffinity () dans Activity qui terminera l'activité en cours et toutes les activités parentes, mais elle ne fonctionne que dans Android 4.1 ou supérieur.

Pour API 16+, utilisez

finishAffinity();

Pour les moins de 16 ans, utilisez

ActivityCompat.finishAffinity(YourActivity.this);

J'espère que cela aide!


21

De developer.android.com :

public void finishAffinity ()

Ajouté au niveau API 16

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é. Ceci est généralement utilisé lorsqu'une application peut être lancée sur une autre tâche (telle qu'une ACTION_VIEW d'un type de contenu qu'il comprend) et que l'utilisateur a utilisé la navigation vers le haut pour passer de la tâche actuelle à sa propre tâche. Dans ce cas, si l'utilisateur a accédé à d'autres activités de la deuxième application, toutes ces activités doivent être supprimées de la tâche d'origine dans le cadre du changement de tâche.

Notez que cette finition ne vous permet pas de fournir des résultats à l'activité précédente et une exception sera levée si vous essayez de le faire.


19

En passant, bon à savoir
Cette réponse fonctionne ( https://stackoverflow.com/a/13468685/7034327 )

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

alors que cela ne fonctionne pas

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() remplace tous les drapeaux précédents et n'ajoute aucun nouveau drapeau.addFlags() fait.

Donc ça marchera aussi

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Grande explication sur la différence entre setFlag et addFlag, merci
Pelanes

13

Si votre application a une version minimum de sdk 16, 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


10

Une solution que j'ai implémentée pour cela (je pense que je l'ai trouvée sur Stack Overflow quelque part, mais je ne m'en souviens pas, donc merci à celui qui l'a fait en premier lieu):

Pour chacune de vos activités, procédez comme suit:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Ensuite, dans votre LoginActivity, remplacez onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
C'est généralement une très mauvaise idée, mais cela peut fonctionner, cela introduit un point de contact qui peut se rompre à l'avenir et il sera difficile de le déboguer. Je vous le dis par expérience :)
Martin Marconcini

10

Pour le bouton de déconnexion sur le dernier écran de l'application, utilisez ce code sur l'écouteur du bouton de déconnexion pour terminer toutes les activités précédentes ouvertes, et votre problème est résolu.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

8
    Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

6
pourquoi FLAG_ACTIVITY_CLEAR_TASK deux fois?
Choletski

1
D'après ce que je comprends, .setFlags remplace les drapeaux précédents et n'ajoute aucun drapeau. .addFlags est ce que vous vouliez utiliser je présume? Cause tout le code ci-dessus i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); se fait anéantir
iOSAndroidWindowsMobileAppsDev

addFlags Works for me
Jamil

1
setFlagsremplacera tous les précédents, donc le dernier setFlagsn'est valide que, les précédents sont remplacés. Vous n'avez donc pas besoin d'appeleri1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal

8

j'ai le même problème que vous pouvez utiliser IntentCompat, comme ceci:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

ce code fonctionne pour moi.

Android api 17


8

Dans mon cas, j'utilise la finishAffinity()fonction dans la dernière activité comme:

finishAffinity()
startHomeActivity()

J'espère que ce sera utile.



6

Connectez-vous> Accueil-> écran 1-> écran 2-> écran 3-> écran 4-> écran 5

sur l'écran 4 (ou tout autre) ->

StartActivity (Connexion)
avec
FLAG_ACTIVITY_CLEAR_TOP


2
Lorsque j'appuie sur le bouton de retour, toutes les activités précédentes sont affichées dans l'ordre où elles étaient. Ces activités doivent être fermées, lorsque vous cliquez sur le bouton de déconnexion, il n'y aura qu'une seule activité dans la pile et ce sera l'activité de connexion. écran de connexion. L'utilisateur démarre à partir de l'écran d'accueil.
Tanmay Mandal

6

pour API> = 15 à API 23 solution simple.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Élaborez votre réponse pour que tout le monde puisse en bénéficier.
Shubhamoy

5

Si vous utilisez startActivityForResult()dans vos activités précédentes, remplacez simplement OnActivityResult()et appelez la finish();méthode à l'intérieur dans toutes les activités .. Cela fera le travail ...


Non, j'utilise startActivityseulement.
Tanmay Mandal

Il sera difficile de maintenir onActivityResultchaque activité. J'ai implémenté la suggestion de DArkO et atteint mon objectif et merci pour l'aide.
Tanmay Mandal

3

Lorsque l'utilisateur clique sur le bouton de déconnexion, puis écrivez le code suivant:

Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Et aussi quand après la connexion si vous appelez une nouvelle activité, n'utilisez pas finish ();


2

Simplement, lorsque vous quittez l'écran de connexion, pas lorsque vous avez terminé l'écran de connexion.

Et puis dans toutes les activités avancées, utilisez ceci pour vous déconnecter:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Cela fonctionne parfaitement.


1

Si vous vous connectez à l'utilisateur screen 1et à partir de là, vous accédez aux autres écrans, utilisez

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Lorsque j'appuie sur le bouton de retour, toutes les activités précédentes sont affichées dans l'ordre où elles étaient. Ces activités doivent être fermées, lorsque vous cliquez sur le bouton de déconnexion, il n'y aura qu'une seule activité dans la pile et ce sera l'activité de connexion.
Tanmay Mandal

Si vous souhaitez ce comportement, vous devez remplacer onKeyDownet onBackPressed(ou onKeyDown, si vous souhaitez prendre en charge les versions Android <2.0) dans chacune de vos activités (sauf la connexion), et startActivity(login)là comme indiqué ci-dessus.
Gabriel Negut

J'ai un bouton qui me mènera à l'écran de connexion pour terminer toutes les activités de la pile, est-ce possible?
Tanmay Mandal

1

J'ai trouvé ça, ça va effacer toute l'histoire et sortir

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);

1

Je suppose que je suis en retard, mais il y a une réponse simple et courte. Il existe une méthode finishAffinity () dans Activity qui terminera l'activité en cours et toutes les activités parentes, mais elle ne fonctionne que dans Android 4.1 ou supérieur.

Pour API 16+, utilisez

finishAffinity ();

Pour les moins de 16 ans, utilisez

ActivityCompat.finishAffinity (YourActivity.this);

J'espère que cela aide!

shareedit a répondu le 27 mai 18 à 8:03

Akshay Taru


0

J'ai trouvé que cette solution fonctionnait sur tous les appareils malgré le niveau API (même pour <11)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

0

Le meilleur moyen de fermer toutes les activités précédentes et d'effacer la mémoire

finishAffinity()
System.exit(0);

0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
            )
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.