Question

Je lis dans la documentation Android qui en mettant ma propriété launchMode d'activité à singleTop ou en ajoutant le drapeau FLAG_ACTIVITY_SINGLE_TOP à mon intention, que l'appel startActivity(intent) serait réutiliser une seule instance d'activité et de me donner l'intention dans le rappel de onNewIntent. Je l'ai fait ces deux choses, et ne onNewIntent les incendies et les feux de onCreate à chaque fois. Les docs disent aussi que this.getIntent() retourne l'intention qui a d'abord passé à l'activité lors de sa création. En onCreate j'appelle getIntent et je reçois un nouveau à chaque fois (je crée l'objet l'intention dans une autre activité et en ajoutant un supplément à elle ... ce supplémentaire devrait être le même à chaque fois que si elle me revenait le même objet intention). Tout cela me porte à croire que mon activité n'agit comme un « top single », et je ne comprends pas pourquoi.

Pour ajouter un peu de fond au cas où je suis tout simplement manquer une étape nécessaire, voici ma déclaration d'activité dans le manifeste et le code que je utilise pour lancer l'activité. L'activité elle-même ne fait rien en ce qui concerne la peine de mentionner ceci:

AndroidManifest.xml:

    <activity
        android:name=".ArtistActivity"
        android:label="Artist"
        android:launchMode="singleTop">
    </activity>     

dans mon appel Activité:

        Intent i = new Intent();
        i.putExtra(EXTRA_KEY_ARTIST, id);
        i.setClass(this, ArtistActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(i);
Était-ce utile?

La solution

Avez-vous vérifié si onDestroy() a été appelé ainsi? C'est probablement pourquoi onCreate() s'invoqué chaque fois au lieu de onNewIntent(), qui ne serait appelée si l'activité est déjà existante.

Par exemple, si vous laissez votre activité via le bouton BACK-il est détruit par défaut. Mais si vous allez plus haut sur la pile d'activité dans d'autres activités et de là, appelez votre ArtistActivity.class encore, il va sauter onCreate() et aller directement à onNewIntent(), parce que l'activité a déjà été créé et depuis que vous avez défini comme singleTop Android ne crée pas un nouvelle instance de celui-ci, mais de prendre celui qui est déjà couché autour.

Ce que je fais pour voir ce qui se passe je mettre en œuvre des fonctions fictives pour tous les différents états de chaque activité, donc je toujours maintenant ce qui se passe:

@Override
public void onDestroy() {
    Log.i(TAG, "onDestroy()");
    super.onDestroy();
}

Idem pour onRestart(), onStart(), onResume(), onPause(), onDestroy()

Si ce qui précède (BACK-bouton) n'a pas votre problème, la mise en œuvre de ces mannequins va au moins vous aider à déboguer un peu mieux.

Autres conseils

La réponse acceptée est pas tout à fait correct. Si OnDestroy () a été appelée précédemment, alors oui, onCreate () serait toujours appelé. Cependant, cette affirmation est fausse : « Si vous allez plus haut sur la pile d'activité dans d'autres activités et d'appeler là-bas votre nouveau ArtistActivity.class il sautera onCreate () et aller directement à onNewIntent () »

La section "singleTop" de http://developer.android.com/guide /components/tasks-and-back-stack.html explique clairement comment il fonctionne (attention au texte en gras ci-dessous, je l'ai aussi prouvé à travers mon propre débogage):

Une intention arrive pour;

"Par exemple, supposons que consiste l'activité racine A des activités B, C, la pile de retour d'une tâche et D sur le dessus (D est sur le dessus la pile est ABCD). une activité de type D. Si D est le mode de lancement par défaut « standard », une nouvelle instance de la classe est lancée et la pile devient ABCDD. Cependant, si le mode de lancement de d'est « singleTop », l'instance existante de D reçoit l'intention par onNewIntent (), parce qu'il est au sommet de la pile la pile reste ABCD. Cependant, si l'intention arrive pour une activité de type B, une nouvelle instance de B est ajouté à la pile, même si son le mode de lancement est "singleTop". "

En d'autres termes, le démarrage d'une activité par SINGLE_TOP ne réutiliser l'activité existante si elle est déjà au sommet de la pile . Il ne fonctionnera pas si une autre activité dans cette même tâche est en haut (par exemple, l'activité qui est en cours d'exécution startActivity (SINGLE_TOP)); une nouvelle instance sera créée à la place.

Voici deux façons de résoudre ce afin que vous obtenez le comportement de SINGLE_TOP que vous voulez - l'objectif général est de réutiliser une activité existante, au lieu de créer un nouveau ...

Première façon (comme décrit dans la section des commentaires du accepté    répondre): Vous pouvez ajouter un launchMode de « singleTask » à votre activité. Cela forcerait onNewIntent () parce singleTask signifie qu'il ne peut y avoir une instance d'une activité particulière dans une tâche donnée. Ceci est une solution peu hacky bien parce que si votre application a besoin de plusieurs instances de cette activité dans une situation particulière (comme je le fais pour mon projet), vous êtes foutus.

Deuxième façon (mieux): Au lieu de FLAG_ACTIVITY_SINGLE_TOP, utilisez FLAG_ACTIVITY_REORDER_TO_FRONT. Cela réutiliser l'instance d'activité existante en le déplaçant vers le haut de la pile (onNewIntent () sera appelé comme prévu).

Le but principal de FLAG_ACTIVITY_SINGLE_TOP est d'empêcher la création d'instances multiples d'une activité. Par exemple, lorsque cette activité peut être lancée par une intention qui vient de l'extérieur de la tâche principale de votre application. Pour la commutation interne entre les activités dans mon application, j'ai trouvé que FLAG_ACTIVITY_REORDER_TO_FRONT est généralement ce que je veux à la place.

Définissez cet indicateur à votre intention:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top