69 votes

Retour d'une activité à l'aide de browseUpFromSameTask ()

J'ai deux activités, A et B. Lorsque l'activité est commencé, il accède à l' Intent passée (car l' Bundle est null, comme cela doit être la première fois), et affiche des informations en conséquence:

CustInfo m_custInfo;
...
protected void onCreate(Bundle savedInstanceState)
{
    ...
    Bundle bundle = (savedInstanceState == null) ? getIntent().getExtras() : savedInstanceState;
    m_custInfo = (CustInfo) m_bundle.getSerializable("CustInfo");
    if (m_custInfo != null
        ...
}

Cela fonctionne bien la première fois. L' EditText contrôles et ListView sont remplis correctement.

Désormais, lorsqu'un élément de la liste est cliqué, l'activité B est a commencé à montrer plus de détails:

m_custInfo = m_arrCustomers.get(pos);

Intent intent = new Intent(A.this, B.class);
intent.putExtra("CustInfo", m_custInfo); // CustInfo is serializable
// printing this intent, it shows to have extras and no flags

startActivityForResult(intent, 1);

Juste avant acivity B est démarré, le cadre des appels A remplacé onSaveInstanceState():

protected void onSaveInstanceState(Bundle outState)
{
    super.onSaveInstanceState(outState);

    outState.putSerializable("CustInfo", m_custInfo);
}

Dans l'activité B, lorsque le bouton est enfoncé dans la barre d'action, je veux retourner à l'activité et à ce qu'il soit dans le même état qu'il était avant:

public boolean onOptionsItemSelected(MenuItem item)
{
    if (item.getItemId() == android.R.id.home)
    {
        Intent intent = NavUtils.getParentActivityIntent(this);
        // printing this intent, it shows to have flags but no extras

        NavUtils.navigateUpFromSameTask(this); // tried finish() here but that created an even bigger mess
        return true;
    }
    ...
}

C'est ici que réside le problème, quand, en onCreate() de l'activité Un deuxième temps, l' Bundle paramètre null et getExtras() retours null. Depuis onSaveInstanceState() a été appelé, je me serais attendu à l' Bundle paramètre de non-null.

J'ai lu à propos de ce problème sur d'autres sites web, ont essayé les suggestions, mais rien ne fonctionne.

133voto

yonojoy Points 1121

Si vous souhaitez que votre application à réagir de cette façon, vous devez déclarer le mode de lancement de votre activité en tant que:

android:launchMode="singleTop"

dans votre AndroidManifest.xml.

Sinon, android utilise la norme de mode de lancement, ce qui signifie

"Le système crée une nouvelle instance de l'activité dans le objectif de la tâche"

et votre activité est recréée (voir Android documentation).

Avec singleTop le système vous renvoie à votre activité existante (avec l'original en sus), si il est sur le dessus de la pile de retour de la tâche. Il n'est pas nécessaire de mettre en œuvre onSaveInstanceState dans cette situation.

savedInstanceState est null dans votre cas, parce que votre activité n'a pas été arrêté par l'OS.

Avis (merci, développeur android pour pointant vers le présent):

Bien que ce soit une solution à la question, il ne fonctionnera pas si l'activité de l'un renvoie à l'est pas sur le dessus de la pile de retour. Prenons le cas de l'activité de départ de B, qui est au début de C, et C est parent de l'activité est configuré pour être A. Si vous appelez NavigateUpFromSameTask() de C, l'activité sera recréé, parce que l'Un n'est pas en haut de la pile.

Dans ce cas, on peut utiliser ce bout de code à la place:

Intent intent = NavUtils.getParentActivityIntent(this); 
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP); 
NavUtils.navigateUpTo(this, intent);

21voto

Mark Doliner Points 196

Option 1

Remplacer getParentActivityIntent() de l'activité B et indiquez les extras nécessaires par l'activité A:

@Override
public Intent getParentActivityIntent () {
    Intent intent = super.getParentActivityIntent();
    intent.putSerializable("CustInfo", m_custInfo);
    return intent;
}

Remarque: Si vous utilisez ActionBarActivity et la barre d'outils de la bibliothèque de prise en charge, alors vous aurez besoin de remplacer getSupportParentActivityIntent(), à la place.

J'ai l'impression que c'est la solution la plus élégante qu'il fonctionne indépendamment de la façon dont l'utilisateur de naviguer à l'activité B. Les deux autres options que je liste ci-dessous ne fonctionnent pas correctement si l'utilisateur accède directement à l'activité B sans passer par activité, par exemple si l'activité B est enregistré en tant que gestionnaire d'URL pour https://www.example.com/customer/TheLaTrattoria. Je pense que ce scénario est la raison pour laquelle le " up " de navigation de l'API est compliqué et ne pas simplement agir comme un idiot bouton de retour.

L'inconvénient de cette solution est que le niveau de départ-un-nouveau-activité d'animation de transition est utilisé plutôt que le retour à l'ancienne activité d'animation.

Option 2

Si vous êtes sûr que l'activité de B n'est jamais lancé à partir de votre application, alors vous pouvez intercepter le bouton vers le haut et de le traiter comme un idiot bouton de retour en substituant onNavigateUp():

@Override
public boolean onNavigateUp () {
    onBackPressed();
    return true;
}

Remarque: Si vous utilisez ActionBarActivity et la barre d'outils de la bibliothèque de prise en charge, alors vous aurez besoin de remplacer onSupportNavigateUp(), à la place.

Un avantage de cette solution est que la norme de retour-pour-les-activité d'animation est utilisée.

Option 3

Comme suggéré par yonojoy, vous pouvez définir android:launchMode="singleTop" sur l'activité A.

-1voto

Stan Smith Points 601

Vous mentionnez:

Dans l'activité B, lorsque vous appuyez sur le bouton Haut dans la barre d'actions, je souhaite revenir à l'activité A et la laisser dans le même état qu'auparavant.

Si votre contenu de l'activité A réside dans un fragment, appelez setRetainInstance (true) dans onCreate () du fragment.

Ensuite, l’instance Fragment sera conservée dans toutes les activités de loisir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X