Effacer toute la pile de l'histoire et commencer une nouvelle activité sur Android
est-il possible de démarrer une activité sur la pile, en effaçant toute l'histoire avant elle?
la situation
j'ai une pile d'activités qui va A->B->C ou B->C (l'écran a sélectionne le token users, mais beaucoup d'utilisateurs n'ont qu'un seul token).
dans l'écran C l'utilisateur peut prendre une action qui rend l'écran b invalide, de sorte que l'application veut les prendre à l'écran, peu importe si elle est déjà dans la pile. L'écran devrait alors être le seul élément sur la pile dans mon application.
Notes
il y a beaucoup d'autres questions similaires, mais je n'ai rien trouvé qui réponde à cette question exacte. J'ai essayé d'appeler getParent().finish()
- cela aboutit toujours à une exception de pointeur nul. FLAG_ACTIVITY_CLEAR_TOP
ne fonctionne que si l'activité est déjà sur la pile.
10 réponses
dans le niveau 11 de L'API, un nouvel indicateur D'intention a été ajouté juste pour cela: .FLAG_ACTIVITY_CLEAR_TASK
juste pour clarifier, utilisez ceci:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
malheureusement pour API lvl <= 10, Je n'ai pas encore trouvé une solution propre à cela. La "Donthackandroidliketh Cette" solution est en effet pure hackery. Vous ne devriez pas le faire. :)
Edit:
Comme par @ Ben Pearson , commentaire, pour API <=10 maintenant, on peut utiliser IntentCompat classe pour la même chose. On peut utiliser le drapeau IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
pour effacer la tâche. Vous pouvez donc également prendre en charge le niveau 11 de l'API pre.
Cas 1: seulement deux activités A et B:
ici le flux D'activité est A - > B.En cliquant sur backbutton à partir de B Nous devons fermer l'application alors tout en commençant L'activité B à partir d'un appel juste terminer () cela empêchera android de stocker L'activité A dans le dos.eg for activity A is Loding / Splash screen of application.
Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();
cas 2: Plus de deux activités:
S'il y a un flux comme A->B->C->D->B et en cliquant sur le bouton retour dans L'activité B tout en venant de L'activité D. Dans 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 commencée dans les coulisses plutôt qu'une nouvelle instance à cause de L'intention.FLAG_ACTIVITY_CLEAR_TOP et intention.FLAG_ACTIVITY_NEW_TASK nettoie la pile et en fait la première.Ainsi, lorsque nous appuierons sur le bouton Retour, toute l'application sera terminée.
avec la nouvelle Version D'Android >= API 16 utilisez finishAffinity()
l'approche Convient pour > = API 16.
Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
- le Son est le même que le démarrage d'une nouvelle Activité, puis de les effacer de la pile.
- ou redémarrer vers MainActivity/FirstActivity.
j'ai passé quelques heures sur ce trop ... et convenez que FLAG_ACTIVITY_CLEAR_TOP ressemble à ce que vous voudriez: effacer la pile entière, sauf pour l'activité en cours de lancement, de sorte que le bouton de retour sort de l'application. Cependant, comme Mike Repass l'a mentionné, FLAG_ACTIVITY_CLEAR_TOP ne fonctionne que lorsque l'activité que vous lancez est déjà dans la pile; lorsque l'activité n'est pas là, le flag ne fait rien.
Que faire? Mettre l'activité en cours de lancement dans la pile avec FLAG_ACTIVITY_NEW_TASK, ce qui fait de cette activité le début d'une nouvelle tâche sur la pile history. Puis ajoutez le drapeau FLAG_ACTIVITY_CLEAR_TOP.
maintenant, quand FLAG_ACTIVITY_CLEAR_TOP va trouver la nouvelle activité dans la pile, elle sera là et sera retirée avant que tout le reste ne soit effacé.
voici ma fonction logout; le paramètre View est le bouton auquel la fonction est attachée.
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 de retour Android doit fonctionner comme dans un navigateur web.
je peux penser à un moyen de le faire, mais c'est tout un piratage.
-
faites vos activités
singleTask
en l'ajoutant auAndroidManifest
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"/>
-
Étendre
Application
qui va contenir la logique de l'endroit 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 manier le bouton de retour à pop()
à partir de la pile.
encore une fois, vous ne devriez pas faire ceci:)
immédiatement après avoir commencé une nouvelle activité, en utilisant startActivity
, assurez-vous d'appeler finish()
pour que l'activité actuelle ne soit pas empilée derrière la nouvelle.
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);
j'ai trouvé trop simple hack juste faire ce ajouter un nouvel élément dans AndroidManifest
comme: -
<activity android:name=".activityName"
android:label="@string/app_name"
android:noHistory="true"/>
le android:noHistory
effacera votre activité indésirable de la pile.
parfois, votre émulateur android pourrait ne pas se connecter à l'outil DDMS eclipse et demander à adb de démarrer manuellement. Dans ce cas, vous pouvez lancer ou arrêter la BAD en utilisant la commande prompt.