51 votes

Problème de classement de la pile d'activités lors du lancement d'une application à partir du programme d'installation d'applications Android et à partir de l'écran d'accueil

Pour les tests, je suis en permettant à mon application APK pour être téléchargé et installé via une URL. Une fois téléchargé sur le téléphone, il peut être lancé avec l'application Android de l'installateur qui donne à l'utilisateur une option pour l'installer sur leur appareil, puis l'exécuter.

Examiner si nous avons téléchargé et exécuté l'application de la manière décrite ci-dessus. Les principales applications de l'activité dans mon application est une page de connexion (Activity A). Une fois l'utilisateur authentifié, elles sont prises à la zone principale de l'application, par exemple, Activity B. Alors maintenant, l'activité actuelle de la pile de cette tâche est - A > B.

Je puis appuyez sur le bouton d'accueil sur le téléphone et je suis pris à l'écran d'accueil Android. Je re-lancer mon application via l'icône dans le menu, et je suis pris à l' Activity A, au lieu de Activity B. Soit l'activité de la pile est maintenant A > B > A, ou il y a maintenant deux tâches distinctes de l'activité, de meules A > B, et A respectivement. Ce que je veux, c'est être ramené à l' Activity B quand je relance l'application. En appuyant sur l'arrière alors que, dans cet état me ramène à l' Activity B.

Ce comportement indésirable se produit uniquement si j'ai d'abord ouvrir l'application via le programme d'installation, et pas si j'ouvre l'application via l'écran d'accueil/menu.

J'ai regardé dans la façon dont les activités sont en cours de démarrage par chaque mécanisme. Lorsque nous utilisons l'application de l'installateur, nous voyons les journaux suivants:

INFO/ActivityManager(XXXX): Starting activity: Intent { dat=file:///mnt/sdcard/download/[my app].apk cmp=com.android.packageinstaller/.InstallAppProgress (has extras) }
INFO/ActivityManager(XXXX): Starting activity: Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=[my package]/[Activity A] }

via écran / écran d'accueil:

INFO/ActivityManager(XXXX): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=[my package]/[Activity A] }

Lorsqu'il est démarré avec le programme d'installation, nous voyons que c'est à l'aide de l'indicateur 0x10000000, mais lorsqu'il est démarré avec le lanceur, nous voyons que c'est à l'aide de 0x10200000. Il est également à l'aide d'une intention catégorie.

À partir de la docs nous de voir les drapeaux sont:

public static final int FLAG_ACTIVITY_NEW_TASK
Constant Value: 268435456 (0x10000000)

public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
Constant Value: 2097152 (0x00200000)

Le drapeau FLAG_ACTIVITY_RESET_TASK_IF_NEEDED (qui est utilisé lorsque l'application est lancée à partir de l'écran de lancement) semble généralement de prévenir une nouvelle tâche d'être créé si il en existe déjà un, et de restaurer la dernière activité. C'est le comportement souhaité. Pourquoi n'est-il pas de travail dans cette situation? Est-ce que je peux faire pour m'assurer que ma demande sera toujours de me rendre à la dernière Activité qu'il a été commencé par le biais de l'application de l'installateur/lanceur?

Si j'utilise singleTask il va toujours me ramener à l'activité principale (Activity A) à chaque fois que je lance l'application (ce qui n'est également pas souhaitable).

Voici une question que j'ai trouvé où quelqu'un est confronté à un problème similaire (qui n'a pas accepté de répondre): App perd sa capacité à retenir sa pile lors du lancement d'une autre application.

EDIT: Vérification de l'indicateur FLAG_ACTIVITY_BROUGHT_TO_FRONT en onCreate() de notre lanceur d'activité (et puis de terminer si elle est définie) semble résoudre le symptôme principal, mais clairement la question sous-jacente est toujours là. Est-il plus complet fix?

EDIT2: Le même résultat se produit lorsque vous télécharger/exécuter l'application à partir de l'Android Market, de sorte que certaines des informations ci-dessus peuvent ne pas être pertinentes.

30voto

Alik Elzin - kilaka Points 4694

Ajout de la réponse fournie par antonyt:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
        // Activity was brought to front and not created,
        // Thus finishing this will get us to the last viewed activity
        finish();
        return;
    }

    // Regular activity creation code...
}
 

12voto

Femi Points 42054

La question sous-jacente que je crois est que l' Intents utilisées sont différentes entre le lanceur et le programme d'installation. Dans la mesure où vous êtes l'obtention de différents Intention des indicateurs que vous allez obtenir de lancement de comportement. Vous pouvez jeter avec le lancement modes et vous pouvez être en mesure d'obtenir un résultat cohérent, mais fondamentalement, ces différentes Intentions de produire des résultats différents.

Votre correction (ou quelque chose comme cela) est probablement votre meilleur pari.

0voto

Nathan Fig Points 3719

Votre problème tient probablement au fait que le programme d'installation de l'application n'utilise pas la catégorie LAUNCHER, contrairement au lanceur.

Ce bogue a été documenté ailleurs:

L'application démarre toujours à partir de l'activité racine au lieu de reprendre l'état d'arrière-plan (bogue connue)

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