Tout d'abord, si vous êtes ciblage des dispositifs aussi haut que l'API 17 (Android 4.2), à l'ensemble de l' targetSdkVersion
- 17 dans votre manifeste. Cela ne veut pas briser le support pour les anciens appareils, il rend juste les choses fonctionnent correctement pour les appareils récents. Bien sûr, cela ne résout pas votre problème, c'est juste bon de le faire.
Que Devriez-Vous Utiliser?
Je suppose que vous basez votre code de la Ancestraux de Navigation exemple sur cette page. Vous avez utilisé le second exemple:
Intent upIntent = new Intent(this, MyParentActivity.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is not part of the application's task, so create a new task
// with a synthesized back stack.
TaskStackBuilder.from(this)
.addNextIntent(new Intent(this, MyGreatGrandParentActivity.class))
.addNextIntent(new Intent(this, MyGrandParentActivity.class))
.addNextIntent(upIntent)
.startActivities();
finish();
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
Pour le comportement que vous voulez, cependant, vous avez besoin de remplacer NavUtils.navigateUpTo
avec:
upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(upIntent);
finish();
Pourquoi faut-il travailler sur ICS et plus Tôt?
En général, le soutien de la bibliothèque est d'essayer d' approximatif, le comportement introduit plus tard dans les Api. Dans le cas d' NavUtils
, la bibliothèque de prise en charge est d'essayer de rapprocher le comportement introduit dans l'API 16 (un.k.un. Android 4.1). Pour le pré-API 16 plates-formes, NavUtils utilise:
@Override
public void navigateUpTo(Activity activity, Intent upIntent) {
upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(upIntent);
activity.finish();
}
Cela ressemble à travers la pile de retour pour une instance de l'activité indiquée en upInent
. Si il en trouve un, il efface tout jusqu'à elle et la restaure. Sinon il vient de lance de l'activité.
Sur API+ de 16 ans plus tard, les plates-formes, le soutien de la bibliothèque mains des choses hors de l'appel des indigènes dans l' Activity
API. Selon les docs:
public boolean navigateUpTo (Intention upIntent)
Naviguer à partir de cette activité à l'activité visée par upIntent, la finition de cette activité dans le processus. Si l'activité indiquée par upIntent existe déjà dans la tâche de l'histoire, de cette activité et tous les autres avant que l'indication de l'activité dans l'histoire de la pile sera fini.
Si indiqué, l'activité n'apparaît pas dans l'histoire de la pile, ce sera la fin de chaque activité dans cette tâche jusqu'à la racine des activités de la tâche est atteint, ce qui entraîne une "in-app "maison" de comportement. Cela peut être utile dans des applications avec une navigation complexe hiérarchie lorsqu'une activité ne peut être atteint par un chemin ne passant pas par le biais d'un canoniques activité parent.
À part cela, il est difficile de savoir si ou non il va lancer l'activité indiquée en upIntent
si elle n'est pas dans la pile de retour. La lecture du code source n'aide pas à clarifier les choses non plus. Toutefois, à en juger par le comportement de votre application est de montrer, il semble qu'il n'a pas de tentative de lancement de l' upIntent
de l'activité.
Indépendamment de la mise en œuvre est bon ou mauvais, le résultat final est que vous voulez l' FLAG_ACTIVITY_CLEAR_TOP
comportement, pas l'API native 16 comportement. Malheureusement, cela signifie que vous devrez reproduire le soutien de la bibliothèque de rapprochement.
Ce qui est Correct?
Avertissement: je ne travaille pas pour Google, donc c'est ma meilleure supposition.
Ma conjecture est que l'API 16+ comportement est le comportement voulu; c'est une interface de mise en œuvre qui a accès à l'Android internes et peuvent faire des choses qui ne sont pas possible par le biais de l'API. Pré-API 16, je ne pense pas qu'il était possible de se détendre la backstack dans ce mode d'autres, que par l'intention de drapeaux. Ainsi, l' FLAG_ACTIVITY_CLEAR_TOP
drapeau est l' approximation la plus proche de l'API 16 comportement disponible à la pré-API 16 plates-formes.
Malheureusement, le résultat est que, entre le maternelle la mise en œuvre et la bibliothèque de prise en charge de la mise en œuvre il y a une violation du principe de moindre étonnement dans votre scénario. Ce qui m'amène à me demander si c'est un imprévu utilisation de l'API. I. e., Je me demande si Android s'attend à ce que vous avez à traverser toute la chemin de navigation pour une activité, de ne pas sauter directement à elle.
Juste au Cas où
Juste pour éviter un possible malentendu, il est possible que quelqu'un pourrait s'attendre à ce shouldUpRecreateTask
grâce à la magie de déterminer que le parent n'est pas dans la pile de retour et passer par le processus de la synthèse de tout pour vous à l'aide de l' TaskStackBuilder
.
Toutefois, shouldUpRecreateTask
détermine fondamentalement si votre activité est lancé directement par votre application (dans ce cas, il renvoie false
), ou si elle a été lancée à partir d'une autre application (dans ce cas, il renvoie true
). À partir de ce livre, la bibliothèque de prise en charge vérifie si l'intention est "action" n'est pas ACTION_MAIN
(je ne comprends pas tout ça), alors que sur l'API 16 plates-formes de il effectue ce test basé sur la tâche de l'affinité. Encore, dans le cas de cette application, les choses fonctionnent à l' shouldUpRecreateTask
retourner false.