2010-01-13 10 views
13

Dans mon application Android, j'ai une activité principale qui sert de point d'entrée à ma demande, qui est configuré dans mon fichier manifeste comme ceci:de retenue état android application en utilisant alwaysRetainTaskState et lauchMode

<activity android:name=".Main" 
       android:label="@string/app_name" 
       android:screenOrientation="portrait" 
       android:alwaysRetainTaskState="true" 
       android:launchMode="singleTask"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

Donc, pour un cas d'utilisation particulier, permet de dire qu'un utilisateur démarre l'application à partir de l'écran d'accueil en cliquant sur l'icône dans le lanceur d'application. Après le démarrage de l'application, l'utilisateur navigue de l'activité principale à l'activité A puis à l'activité B. À ce stade, l'utilisateur décide de vérifier son Facebook, il clique donc sur le bouton d'accueil pour mettre son application en arrière-plan et lance l'application facebook. Après avoir vérifié leur facebook, l'utilisateur veut retourner à mon application, ils appuient sur la touche d'accueil, et lancent l'application depuis le lanceur d'application (comme ils l'ont fait la première fois qu'il a été lancé). Lorsqu'un utilisateur retourne à mon application, je souhaite que l'application revienne à la dernière activité à laquelle l'utilisateur se trouvait lorsque l'application a été placée en arrière-plan, en l'occurrence l'activité B. Dans le fichier manifeste, j'ai Définissez alwaysRetainTaskState = true pour vous assurer que le système d'exploitation ne tue pas les activités de mon application.

Maintenant à ma question: comment puis-je obtenir le comportement que j'ai décrit ci-dessus? Chaque fois que je clique sur l'icône de mon application, elle commence toujours à l'activité principale, quoi qu'il arrive. Je pense que c'est à cause de l'attribut category.LAUNCHER. J'ai essayé android: launchMode = singleTask, mais cela n'a pas fait de différence; ça commence toujours à Main.

Si quelqu'un pouvait clarifier les filtres d'intention, les modes de lancement et les tâches, ce serait génial!

+0

Je pense que cette question est trop vieux, et devrait être mis à jour accrding à http://developer.android.com /guide/components/tasks-and-back-stack.html –

Répondre

3

J'ai résolu ceci en ajoutant le DispatcherActivity sans écran et en le rendant par défaut (en utilisant le même filtre d'intention). Dans sa méthode onCreate, vous créez et appelez l'intention en fonction d'une valeur par défaut raisonnable (votre activité principale par exemple) OU en fonction d'un jeton enregistré qui identifie quelle activité doit être démarrée. Ce jeton est enregistré/actualisé dans onStop méthode de toute activité que vous souhaitez appeler au redémarrage. Vous pouvez enregistrer ce jeton dans les préférences.

Le rationnel ici est que la dernière activité qui était visible exécutera la méthode onStop lorsqu'elle est interrompue. Mise en garde ici: J'ai implémenté ce modèle et cela a raisonnablement bien fonctionné. Cependant, il semble ne pas jouer trop bien avec l'histoire et finalement j'ai juste abandonné et arraché ce code. Personne ne s'est plaint jusqu'à présent.

+0

c'est une solution intuitive. si vous revenez à mon exemple, si j'ai stocké un jeton dans l'activité B onStop, et vérifié ce jeton dans DispatcherActivity et démarré l'activité B lorsque le jeton est défini, cela vous ramènerait à la dernière activité, mais ne serait pas vous devez stocker un jeton pour les activités que l'utilisateur a visité avant B (activité A dans mon exemple)? – jlim

+0

Étonnamment non. Je pense qu'en raison de la mise en cache des informations, votre activité B n'est pas recréée à partir de rien et conserve son historique. Ainsi, par exemple, lorsque vous appuyez sur le bouton de retour, il va savoir aller à l'activité de l'appelant. Donc, une des choses que vous devez faire quand vous appelez l'activité du répartiteur, vous devez également exécuter finish() pour que le Dispatcher ne soit plus appelé quand vous cliquez sur le bouton précédent – Bostone

+0

J'ai l'impression qu'il y a une meilleure façon de faire. le menu du sélecteur d'application (appui long touche accueil) le gère très bien .. je ne vois pas pourquoi nous ne pouvons pas reproduire ce comportement dans la barre d'application .. – jlim

8

Pour votre information singleTask est pas ce que vous voulez, car il commence une nouvelle tâche:

http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

Comment lancez-vous l'activité B? Des modes de lancement non standard ou des drapeaux Intent?

+0

non je n'ai pas de filtres d'intention pour B, et je fais simplement un startActivity (nouveau Intent (this, B.class)); – jlim

+2

oui je ne sais pas pourquoi tant de SO réponses à des questions comme celle-ci (application reprenant etc) suggèrent d'utiliser singleTask - ce n'est généralement pas ce que vous voulez ... –

+0

Vous avez absolument raison! Dans mon cas, singleTask était la cause de ce problème. – Apfelsaft

7

Pour ceux qui viennent ici avec des problèmes similaires, j'ai trouvé quelque chose d'étrange qui pourrait être ce que vous voyez ... peut-être. Dire que j'ai une application avec des activités A -> B -> C etc J'ai eu des problèmes avec mon application toujours "reprendre" à A si elle a été lancée à partir de la liste des applications alias lanceur. Reprise de l'écran "retraits" (longue pression à la maison) présenterait le comportement de reprise correcte bien (reprendre à B ou C comme prévu). Mon manifeste n'avait rien de spécial, j'ai toujours définiRetainTaskState = "true" dans mon activité racine, et le mode de lancement est par défaut (standard).

Je chargeais l'apk sur mon téléphone via un site Web. Après le téléchargement et l'installation, Je voudrais appuyer sur "Ouvrir" pour lancer l'application tout de suite. Pour une raison quelconque (après la désinstallation de l'application) j'ai fatigué le téléchargement à nouveau, l'installation, mais alors je appuyé sur le bouton "Terminé" à la place. Le lancement de l'application à partir de la liste lanceur/"toutes les applications" a le même comportement de reprise que la reprise. En d'autres termes, mes problèmes étaient causés par le processus d'installation lorsque vous cliquez sur "Ouvrir".

J'ai vérifié cette "solution" sur API10 (2.3.5) et API15 (4.0.4)

+0

Avez-vous déjà trouvé une solution pour cela? –

+4

Non. Il y a un bug à ce sujet ici (créé par quelqu'un d'autre): https://code.google.com/p/android/issues/detail?id=38194&q=app+resume+open+done&colspec=ID+Type + Statut + Propriétaire + Résumé + Étoiles Je trouve difficile de comprendre comment il n'y a pas plus de gens agacés par ce comportement: / –

Questions connexes