Toutes les activités de mon application nécessitent qu'un utilisateur soit connecté pour voir. Les utilisateurs peuvent se déconnecter de presque toutes les activités. C'est une exigence de l'application. À tout moment, si l'utilisateur se déconnecte, je veux envoyer l'utilisateur à la connexion Activity
. À ce stade, je veux que cette activité se trouve au bas de la pile d'historique afin que le fait d'appuyer sur le bouton "retour" ramène l'utilisateur à l'écran d'accueil d'Android.
J'ai vu cette question posée à différents endroits, toutes ont répondu avec des réponses similaires (que je décris ici), mais je veux la poser ici pour recueillir des commentaires.
J'ai essayé d'ouvrir l'activité de connexion en définissant ses Intent
indicateurs FLAG_ACTIVITY_CLEAR_TOP
qui semblent faire comme indiqué dans la documentation, mais n'atteint pas mon objectif de placer l'activité de connexion au bas de la pile d'historique et d'empêcher l'utilisateur de revenir en arrière aux activités enregistrées précédemment. J'ai également essayé d'utiliser android:launchMode="singleTop"
pour l'activité de connexion dans le manifeste, mais cela n'atteint pas mon objectif non plus (et semble n'avoir aucun effet de toute façon).
Je crois que je dois effacer la pile d'historique ou terminer toutes les activités précédemment ouvertes.
Une option consiste à demander à chaque activité de onCreate
vérifier l'état de connexion et, finish()
si elle n'est pas connectée. Je n'aime pas cette option, car le bouton de retour sera toujours disponible pour une utilisation, en revenant à la fermeture des activités.
L'option suivante consiste à conserver une LinkedList
référence à toutes les activités ouvertes qui est accessible statiquement de partout (peut-être à l'aide de références faibles). Lors de la déconnexion, j'accéderai à cette liste et parcourrai toutes les activités précédemment ouvertes, en invoquant finish()
chacune d'entre elles. Je vais probablement commencer à implémenter cette méthode bientôt.
Je préfère cependant utiliser une Intent
supercherie de drapeau pour y parvenir. Je serais plus que ravi de constater que je peux répondre aux exigences de mon application sans avoir à utiliser l'une des deux méthodes décrites ci-dessus.
Existe-t-il un moyen d'y parvenir en utilisant Intent
ou en manifestant des paramètres, ou ma deuxième option, maintenir une LinkedList
des activités ouvertes est-elle la meilleure option? Ou existe-t-il une autre option que je néglige complètement?
Il semble qu'un rite de passage qu'un nouveau programmeur Android passe une journée à rechercher ce problème et à lire tous ces threads StackOverflow. Je suis maintenant nouvellement initiée et je laisse ici trace de mon humble expérience pour aider un futur pèlerin.
Tout d'abord, il n'y a pas de moyen évident ou immédiat de le faire selon mes recherches
(as of September 2012).
Vous penseriez que vous pourriez simplestartActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)
mais non .Vous POUVEZ faire
startActivity(new Intent(this, LoginActivity.class))
avecFLAG_ACTIVITY_CLEAR_TOP
- et cela amènera le framework à rechercher dans la pile, à trouver votre instance initiale précédente de LoginActivity, à la recréer et à effacer le reste de la pile (vers le haut). Et puisque la connexion est probablement au bas de la pile, vous avez maintenant une pile vide et le bouton Retour quitte simplement l'application.MAIS - cela ne fonctionne que si vous avez précédemment laissé cette instance originale de LoginActivity en vie à la base de votre pile. Si, comme de nombreux programmeurs, vous avez choisi
finish()
celaLoginActivity
une fois que l'utilisateur s'est connecté avec succès, alors ce n'est plus sur la base de la pile et laFLAG_ACTIVITY_CLEAR_TOP
sémantique ne s'applique pas ... vous finissez par en créer un nouveauLoginActivity
au-dessus de la pile existante. Ce qui n'est presque certainement PAS ce que vous voulez (comportement étrange où l'utilisateur peut `` revenir '' en arrière de sa connexion à un écran précédent).Donc , si vous avez déjà
finish()
« d laLoginActivity
, vous devez poursuivre un mécanisme pour la suppression de votre pile, puis commencer un nouveauLoginActivity
. Il semble que la réponse de@doreamon
ce fil soit la meilleure solution (au moins à mon humble œil):https://stackoverflow.com/a/9580057/614880
Je soupçonne fortement que les implications délicates de savoir si vous laissez LoginActivity en vie causent beaucoup de confusion.
Bonne chance.
la source
METTRE À JOUR
la super
finishAffinity()
méthode aidera à réduire le code mais à atteindre le même résultat. Il terminera l'activité en cours ainsi que toutes les activités de la pile, utilisezgetActivity().finishAffinity()
si vous êtes dans un fragment.RÉPONSE ORIGINALE
Supposons que LoginActivity -> HomeActivity -> ... -> SettingsActivity indicatif d'appelOut ():
AccueilActivité:
Cela fonctionne pour moi, j'espère que cela vous sera utile aussi. :)
la source
Si vous utilisez l'API 11 ou une version ultérieure, vous pouvez essayer ceci: - cela
FLAG_ACTIVITY_CLEAR_TASK
semble résoudre exactement le problème que vous rencontrez. Évidemment, la foule pré-API 11 devrait utiliser une combinaison de vérification de toutes les activités, comme le suggère @doreamon, ou une autre ruse.(Notez également: pour l'utiliser, vous devez passer
FLAG_ACTIVITY_NEW_TASK
)la source
finish();
fera juste le travail pour éviter de revenir en arrière après la déconnexion. Quel est le besoin de définir des drapeaux?J'ai aussi passé quelques heures là-dessus ... et je suis d'accord pour dire que FLAG_ACTIVITY_CLEAR_TOP ressemble à ce que vous voudriez: effacer toute la pile, à l'exception de l'activité en cours de lancement, donc le bouton Retour quitte l'application. Pourtant, 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; quand l'activité n'est pas là, le drapeau ne fait rien.
Que faire? Placez 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 d'historique. Ajoutez ensuite l'indicateur FLAG_ACTIVITY_CLEAR_TOP.
Maintenant, lorsque FLAG_ACTIVITY_CLEAR_TOP va chercher la nouvelle activité dans la pile, elle sera là et sera relevée avant que tout le reste ne soit effacé.
Voici ma fonction de déconnexion; le paramètre View est le bouton auquel la fonction est attachée.
la source
FLAG_ACTIVITY_CLEAR_TASK
n'a pas encore été ajoutéBeaucoup de réponses. Peut-être que celui-ci aidera également
Version Kotlin-
la source
Utilisez-le, il devrait vous être utile. Réponse xbakesx légèrement modifiée.
la source
La solution acceptée n'est pas correcte, elle a des problèmes car l'utilisation d'un récepteur de diffusion n'est pas une bonne idée pour ce problème. Si votre activité a déjà appelé la méthode onDestroy (), vous n'aurez pas de récepteur. La meilleure solution consiste à avoir une valeur booléenne sur vos préférences partagées et à la vérifier dans la méthode onCreate () de votre activité. S'il ne doit pas être appelé lorsque l'utilisateur n'est pas connecté, terminez l'activité. Voici un exemple de code pour cela. Si simple et fonctionne pour toutes les conditions.
la source
onResume()
méthode. Parce que lorsque vous appuyez sur le bouton de retour, l'activité est plus susceptible de reprendre au lieu d'être créée.Parfois
finish()
ne fonctionne pasJ'ai résolu ce problème avec
finishAffinity()
la source
Je suggérerais une approche différente de cette question. Ce n'est peut-être pas le plus efficace, mais je pense que c'est le plus facile à appliquer et nécessite très peu de code. L'écriture du code suivant dans votre première activité (activité de connexion, dans mon cas) ne permettra pas à l'utilisateur de revenir aux activités précédemment lancées après la déconnexion.
Je suppose que LoginActivity est terminé juste après la connexion de l'utilisateur, de sorte qu'il ne peut pas y revenir plus tard en appuyant sur le bouton de retour. À la place, l'utilisateur doit appuyer sur un bouton de déconnexion dans l'application pour se déconnecter correctement. Ce que ce bouton de déconnexion implémenterait est une intention simple comme suit:
Toutes les suggestions sont les bienvenues.
la source
La réponse choisie est intelligente et délicate. Voici comment je l'ai fait:
LoginActivity est l'activité racine de la tâche, définissez android: noHistory = "true" dans Manifest.xml; Supposons que vous souhaitiez vous déconnecter de SettingsActivity, vous pouvez le faire comme ci-dessous:
la source
Voici la solution que j'ai trouvée dans mon application.
Dans mon LoginActivity, après avoir traité avec succès une connexion, je démarre la suivante différemment selon le niveau de l'API.
Ensuite, dans la méthode onActivityForResult de mon LoginActivity:
Enfin, après avoir traité une déconnexion dans toute autre activité:
Lorsque sur Gingerbread, le fait si j'appuie sur le bouton de retour de MainActivity, la LoginActivity est immédiatement masquée. Sur Honeycomb et versions ultérieures, je viens de terminer la LoginActivity après avoir traité une connexion et elle est correctement recréée après avoir traité une déconnexion.
la source
Cela a fonctionné pour moi:
la source
Commencez votre activité avec StartActivityForResult et pendant que vous vous déconnectez, définissez votre résultat et selon votre résultat, terminez votre activité
la source
La solution fournie par @doreamon fonctionne bien pour tous les cas sauf un:
Si Après la connexion, l'utilisateur de l'écran Killing Login a accédé directement à un écran du milieu. Par exemple, dans un flux de A-> B-> C, naviguez comme: Connexion -> B -> C -> Appuyez sur le raccourci vers la page d'accueil. L'utilisation de FLAG_ACTIVITY_CLEAR_TOP efface uniquement l'activité C, car la maison (A) n'est pas dans l'historique de la pile. Appuyer sur Retour sur un écran nous ramènera à B.
Pour résoudre ce problème, nous pouvons conserver une pile d'activités (Arraylist) et lorsque la maison est pressée, nous devons tuer toutes les activités de cette pile.
la source
Cela est possible en gérant un indicateur dans SharedPreferences ou dans Application Activity.
Au démarrage de l'application (sur l'écran de démarrage), définissez le drapeau = false; Lors de l'événement Click de déconnexion, définissez simplement le drapeau sur true et dans OnResume () de chaque activité, vérifiez si le drapeau est vrai, puis appelez finish ().
Il fonctionne comme un charme :)
la source
en cliquant sur Déconnexion, vous pouvez appeler cela
onActivityResult () de l'activité précédente, appelez à nouveau ce code ci-dessus jusqu'à ce que vous ayez terminé toutes les activités.
la source
Ce que vous voulez faire, c'est appeler logout () et finish () sur vos méthodes onStop () ou onPause (). Cela forcera Android à appeler onCreate () lorsque l'activité sera réactivée car il ne l'aura plus dans sa pile d'activité. Faites ensuite ce que vous dites, dans onCreate (), vérifiez l'état de connexion et transférez-le à l'écran de connexion s'il n'est pas connecté.
Une autre chose que vous pouvez faire est de vérifier l'état de connexion dans onResume () et, si vous n'êtes pas connecté, de terminer () et de lancer l'activité de connexion.
la source