web-dev-qa-db-fra.com

Nouvelle intention () démarre une nouvelle instance avec Android: launchMode = "singleTop"

J'ai l'activité A avec Android:launchMode="singleTop" dans le manifeste.

Si je vais à l’activité B, C et D, j’ai des raccourcis de menu pour revenir à l’activité racine de mes applications (A).

Le code ressemble à ceci:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class);
startActivity(myIntent);

Cependant, au lieu de retourner à l'instance existante A de mon MainActivity.class, une nouvelle instance est créée -> elle passe à onCreate() au lieu de onNewIntent().

Ce n'est pas le comportement attendu, non?

56
znq

Cela devrait faire l'affaire.

<activity ... Android:launchMode="singleTop" />

Lorsque vous créez une intention de démarrer l'application, utilisez:

Intent intent= new Intent(context, YourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

C'est ce qui devrait être nécessaire.

68
Vidar Vestnes

En fin de compte, ce qui a fonctionné pour moi a été le suivant:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
28
znq

Citation de la documentation

Les modes "standard" et "singleTop" diffèrent les uns des autres dans un seul respect: chaque fois qu'il y a une nouvelle intention pour une activité "standard", une nouvelle instance de la classe est créée pour répondre à cette intention. Chaque instance gère une seule intention. De même, un nouvelle instance d'une activité "singleTop" peut également être créé pour gérer un nouveau fichier intention. Cependant, si la tâche cible a déjà une instance existante de l'activité au sommet de sa stack, cette instance recevra la nouvelle intention (dans un appel onNewIntent () ); une nouvelle instance n'est pas créée.

Je ne suis pas sûr à 100% de ce que signifie "existe déjà une instance existante de l'activité", mais votre activité ne remplit peut-être pas cette condition.

singleTask ou singleInstance fonctionnerait-il pour vous? Ou peut-être pourriez-vous essayer de définir FLAG_ACTIVITY_SINGLE_TOP sur l'intention que vous créez pour voir si cela fait une différence, bien que je ne le pense pas.

14
Mark B

Vous pouvez revenir à la même instance existante d’Activity avec Android:launchMode="singleInstance"

dans le manifeste . Lorsque vous revenez à A de B, il peut être nécessaire de finish() pour détruire B.

6
rbin

Tout d'abord, la structure de pile peut être examinée. Pour le mode de lancement: singleTop
Si une instance de la même activité se trouve déjà en haut de la pile de tâches, cette instance sera réutilisée pour répondre à l'intention. 

Toutes les activités sont conservées dans la pile ("premier entré, dernier sorti"), donc si votre activité actuelle est au sommet de la pile et si vous la définissez dans le fichier manifeste.file comme étant singleTop

Android:name=".ActivityA"
Android:launchMode="singleTop"

si vous êtes dans ActivityA, recréez l'activité qu'il ne va pas entrer onCreate reprend onNewIntent () et vous pouvez le voir en créant une notification Not: Si vous n'implémentez pas NewIntent (Intent), vous n'obtiendrez pas de nouvelle intention.

Intent activityMain = new Intent(ActivityA.this,
                        ActivityA.class);

                activityMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                startActivity(activityMain);




    @Override
        protected void onNewIntent(Intent intent) {

            super.onNewIntent(intent);

            notify("onNewIntent");
        }

        private void notify(String methodName) {

            String name = this.getClass().getName();
            String[] strings = name.split("\\.");

            Notification noti = new Notification.Builder(this)
                    .setContentTitle(methodName + "" + strings[strings.length - 1])
                    .setAutoCancel(true).setSmallIcon(R.drawable.ic_launcher)
                    .setContentText(name).build();
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.notify((int) System.currentTimeMillis(), noti);

        }
1
huseyin

En effet, l'activité A d'origine est déjà en cours de destruction au moment où vous la démarrez à partir de B, C ou D. Par conséquent, onCreate sera appelé à la place de onNewIntent (). Une façon de résoudre ce problème est de toujours détruire le A existant (en utilisant FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK en conjonction lorsque startActivity) avant de commencer un nouveau A, onCreate sera toujours appelé et vous introduirez le code de onNewIntent () dans onCreate () en cochant si getIntent ) est l'intention avec laquelle vous avez commencé.

0
Rachel