web-dev-qa-db-fra.com

Supprimer une activité de la pile d'historique

Mon application affiche une activité d'inscription lors de la première utilisation de l'application par l'utilisateur.

  1. ActivitySplashScreen (bienvenue dans le jeu, créer un compte?)
  2. ActivitySplashScreenSignUp (génial, remplissez cette information)
  3. ActivityGameMain (écran de jeu principal)

les activités se lancent donc exactement dans cet ordre, lorsque l'utilisateur clique sur un bouton de chaque écran.

Lorsque l'utilisateur passe de l'activité n ° 2 à l'activité n ° 3, est-il possible d'effacer complètement les piles n ° 1 et n ° 2 de l'historique? J'aimerais que, si l'utilisateur est au n ° 3 et appuie sur le bouton Précédent, il se contente d'afficher l'écran d'accueil au lieu de revenir à l'écran d'accueil.

Je pense que je peux accomplir cela avec des tâches (c.-à-d. Commencer une nouvelle tâche sur # 3) mais je voulais voir s'il y avait une méthode plus simple,

Merci

368
Mark

Vous pouvez y parvenir en définissant Android:noHistoryattribut sur "true" dans les entrées <activity> pertinentes de votre fichier AndroidManifest.xml. Par exemple:

<activity
    Android:name=".AnyActivity"
    Android:noHistory="true" />
614
Aitor Gómez

Vous pouvez utiliser le transfert pour supprimer l'activité précédente de la pile d'activités lors du lancement de la suivante. Il y a un exemple dans APIDemos , mais vous ne faites qu'appeler finish() immédiatement après l'appel de startActivity().

135
Daniel Lew
50
Matthias

Ce n'est probablement pas la façon idéale de le faire. Si quelqu'un a un meilleur moyen, je serai impatient de le mettre en œuvre. Voici comment I a accompli cette tâche spécifique avec sdk pré-version 11.

dans chaque classe que vous voulez partir quand il est temps, vous devez faire ceci:

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

alors celui qui a besoin de déclencher la chaîne de pops de la pile doit simplement appeler ceci quand vous voulez l'initialiser:

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

Ensuite, les activités ne sont pas sur la pile!
Rappelez-vous, vous pouvez commencer une activité, puis commencer à nettoyer derrière elle. L'exécution ne suit pas un seul thread (l'interface utilisateur).

23
Travis

Une des méthodes qui fonctionnent avant l’API 11 consiste à démarrer ActivityGameMain en premier, puis dans la onCreate de cette activité, démarrez votre activité ActivitySplashScreen. La ActivityGameMain n'apparaîtra pas lorsque vous appelez startActivity trop tôt pour le démarrage.

Ensuite, vous pouvez vider la pile lors du démarrage de ActivityGameMain en définissant ces indicateurs sur l’intention:

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

Vous devez également ajouter ceci à ActivitySplashScreen:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

Pour que cette activité ne retourne pas à votre ActivityGameMain.

Je suppose que vous ne voulez pas que l’écran de démarrage revienne en arrière. Pour ce faire, je vous suggère de le régler sur noHistory dans votre AndroidManifest.xml. Ensuite, mettez le code goBackPressed dans votre classe ActivitySplashScreenSignUp.

Cependant, j'ai trouvé quelques moyens de résoudre ce problème. Démarrez une autre application à partir d'une notification lorsque ActivitySplashScreenSignUp est affiché et que l'historique en arrière-plan n'est pas réinitialisé.

Le seul moyen de contourner ce problème est d’utiliser l’API 11:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
21
mxcl

Je l'utilise de cette façon.

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);
17
Smiderle

Je sais que je suis en retard sur ce point (cela fait deux ans que la question a été posée) mais j’ai accompli cela en interceptant la pression du bouton de retour. Plutôt que de rechercher des activités spécifiques, je regarde simplement le nombre et s'il est inférieur à 3, il envoie simplement l'application à l'arrière (en mettant l'application en pause et en renvoyant l'utilisateur à ce qui était en cours d'exécution avant le lancement). Je vérifie moins de trois parce que je n'ai qu'un seul écran d'introduction. En outre, je vérifie le nombre, car mon application permet à l'utilisateur de revenir à l'écran d'accueil via le menu, ce qui leur permet de revenir en arrière sur d'autres écrans comme d'habitude s'il existe des activités autres que l'écran d'introduction sur la pile.

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
    //Check the activity stack and see if it's more than two deep (initial screen and home screen)
    //If it's more than two deep, then let the app proccess the press
    ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
    int activityCount = tasks.get(0).numActivities;

    if (activityCount < 3)
    {
        moveTaskToBack(true);
    }
    else
    {
        super.onBackPressed();
    }
}
8
alphonzo79

Dans le manifeste, vous pouvez ajouter:

Android:noHistory="true"

<activity
Android:name=".ActivityName"
Android:noHistory="true" />

Vous pouvez aussi appeler

finish()

immédiatement après avoir appelé startActivity (..)

6
Anubhav

Il suffit de définir noHistory="true" dans le fichier Manifeste. Cela permet de supprimer les activités du stock.

6

C'est fou que personne n'ait mentionné cette solution élégante. Cela devrait être la réponse acceptée.

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

La clé ici est d'utiliser intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); pour l'intermédiaire Activity. Une fois que le lien du milieu est rompu, la DashActivity sera la première et la dernière de la pile.

Android:noHistory="true" est une mauvaise solution car cela pose des problèmes lorsque vous utilisez le Activity comme rappel, par exemple onActivityResult. C'est la solution recommandée et doit être acceptée.

4
Rowland Mtetezi

pour API> = 15 à API 23, une autre solution ne fonctionne pas dans mon cas. enfin je reçois celui-ci.

 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);
3
Kamal Bunkar

C'est trop tard, mais j'espère que ça aidera. La plupart des réponses ne vont pas dans la bonne direction. Il y a deux simples drapeaux pour une telle chose.

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

À partir de Android docs:

public static final int FLAG_ACTIVITY_CLEAR_TASK Ajouté au niveau 11 de l'API

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the

activité à effacer avant le début de l'activité. En d’autres termes, l’activité devient la nouvelle racine d’une tâche par ailleurs vide et toutes les anciennes activités sont terminées. Ceci ne peut être utilisé qu'avec FLAG_ACTIVITY_NEW_TASK.

3
Nouman Ghaffar

Il suffit d'appeler this.finish () avant de commencerActivité (intention) comme ceci-

       Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
        this.finish();
        startActivity(intent);
1
user8269411