Question

Est-il possible de démarrer une activité sur la pile, la compensation de toute l'histoire avant qu'elle ne?

La situation

J'ai une pile d'activité qui va soit A> B> C ou B> C (écran A sélectionne les utilisateurs jeton, mais de nombreux utilisateurs ont seulement un seul jeton).

Dans l'écran C l'utilisateur peut prendre une action qui rend l'écran invalide B, de sorte que l'application veut les prendre à l'écran A, peu importe que ce soit déjà dans la pile. A l'écran devrait alors être le seul élément de la pile dans mon application.

Remarques

Il y a beaucoup d'autres questions semblables, mais je n'ai rien trouvé qui répond à cette question précise. J'ai essayé d'appeler getParent().finish() - il en résulte toujours une exception de pointeur NULL. FLAG_ACTIVITY_CLEAR_TOP ne fonctionne que si l'activité est déjà sur la pile.

Était-ce utile?

La solution

Dans le niveau API 11 un nouveau drapeau intention a été ajouté juste pour ceci: Intent.FLAG_ACTIVITY_CLEAR_TASK

Pour préciser, utilisez ceci:

Java

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

Kotlin

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Malheureusement pour API lvl <= 10, je n'ai pas encore trouvé une solution propre à ce sujet. Les "DontHackAndroidLikeThis" solution est en effet pur hack. Vous ne devriez pas faire cela. :)

Edit: Comme par @ Ben Pearson commentaire de , pour API <= 10 on peut maintenant utiliser IntentCompat de classe pour la même. On peut utiliser l'indicateur de IntentCompat.FLAG_ACTIVITY_CLEAR_TASK à la tâche claire. Ainsi, vous pouvez soutenir le niveau pré API 11 ainsi.

Autres conseils

Cas 1: Seulement deux activités A et B:

Ici flux d'activité est A-> B .Sur cliquant backbutton de B nous devons fermer l'application puis lors du démarrage de l'activité B de A Finissez juste appel () cela empêchera Android de stocker l'activité A la Backstack.eg pour l'activité A est Loding / écran de démarrage de l'application.

Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();

Cas n ° 2: Plus de deux activitiy:

S'il y a un flux comme A> B> C> D> B et cliquant sur le bouton de retour à l'activité B en venant de l'activité D.In ce cas, nous devrions utiliser.

Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);

Ici l'activité B sera lancé à partir du backstack plutôt que d'une nouvelle instance en raison de Intent.FLAG_ACTIVITY_CLEAR_TOP et Intent.FLAG_ACTIVITY_NEW_TASK efface la pile et en fait le haut one.So quand on appuie sur le bouton retour toute l'application sera terminée.

Avec Android version plus récente> = API 16 utilisation finishAffinity()

approche convient à> = API 16.

Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
  • Son est le même que le démarrage de nouvelles activités, et effacer tous les pile.
  • ou restart pour MainActivity / FirstActivity.

J'ai passé quelques heures sur ce trop ... et acceptez que les sons de FLAG_ACTIVITY_CLEAR_TOP comme ce que vous voulez: effacer l'ensemble de la pile, à l'exception de l'activité en cours de lancement, de sorte que le bouton Précédent pour quitter l'application. Pourtant, comme Mike Repass mentionné, FLAG_ACTIVITY_CLEAR_TOP ne fonctionne que lorsque l'activité que vous lanciez est déjà dans la pile; lorsque l'activité est pas là, le drapeau ne fait rien.

Que faire? Mettre l'activité étant le lancement de la pile avec FLAG_ACTIVITY_NEW_TASK, ce qui rend cette activité le début d'une nouvelle tâche sur la pile de l'histoire. Ensuite, ajoutez le drapeau FLAG_ACTIVITY_CLEAR_TOP.

Maintenant, quand FLAG_ACTIVITY_CLEAR_TOP va trouver la nouvelle activité dans la pile, ce sera là et être tiré vers le haut avant tout le reste est effacé.

Voici ma fonction de fermeture de session; le paramètre View est le bouton auquel ils sont attachés de la fonction.

public void onLogoutClick(final View view) {
    Intent i = new Intent(this, Splash.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    finish();
}

Vous ne devriez pas changer la pile. bouton retour Android devrait fonctionner comme dans un navigateur Web.

Je peux penser à une façon de le faire, mais il est tout à fait un hack.

  • Faites votre Activités singleTask en l'ajoutant à la AndroidManifest Exemple:

    <activity android:name=".activities.A"
              android:label="@string/A_title"
              android:launchMode="singleTask"/>
    
    <activity android:name=".activities.B"
              android:label="@string/B_title"
              android:launchMode="singleTask"/>
    
  • Prolongez Application qui tiendra la logique où aller.

Exemple:

public class DontHackAndroidLikeThis extends Application {

  private Stack<Activity> classes = new Stack<Activity>();

  public Activity getBackActivity() {
    return classes.pop();
  }

  public void addBackActivity(Activity activity) {
    classes.push(activity);
  }
}

De A à B:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class); 
startActivity(this, B.class);

De B à C:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class); 
startActivity(this, C.class);

C:

If ( shouldNotGoBackToB() ) {
  DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
  app.pop();
}

et manipuler le bouton de retour à pop() de la pile.

Encore une fois, vous ne devriez pas le faire:)

Immédiatement après avoir démarré une nouvelle activité, en utilisant startActivity, assurez-vous que vous appelez finish() afin que l'activité en cours ne sont pas empilés derrière le nouveau.

Essayez ceci:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Essayez ci-dessous le code,

Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK| 
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Pour moi pas des méthodes ci-dessus pas de travail.

Il suffit de le faire à effacer toutes les activités précédent :

finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)

J'ai trouvé trop simple bidouille faire juste ce module nouvel élément dans AndroidManifest comme: -

<activity android:name=".activityName"
          android:label="@string/app_name"
          android:noHistory="true"/>

la android:noHistory effacera votre activité indésirable de la pile.

Parfois, votre force émulateur Android ne parvient pas à connecter Eclipse outil DDMS et demander adb pour démarrer manuellement. Dans ce cas, vous pouvez démarrer ou arrêter le adb en utilisant l'invite de commande.

scroll top