New Intent () запускает новый экземпляр с Android: launchMode= " singleTop"


у меня есть активность A С android:launchMode="singleTop" в манифесте.

если я пойду в Activity B,C и D там у меня есть ярлыки меню, чтобы вернуться к моей корневой активности приложений (A).

код выглядит так:

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

однако вместо возврата к уже существующему экземпляру A моего MainActivity.class он создает новый экземпляр -> идет onCreate() вместо onNewIntent().

это не ожидаемое поведение, верно?

6 56

6 ответов:

Это должно сделать трюк.

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

при создании намерения начать использование приложения:

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

Это что необходимо.

что на самом деле сработало для меня в конце концов было так:

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

цитата документация:

"стандартные" и "singleTop" режимы отличаются друг от друга только одним уважение: Каждый раз, когда появляется новое намерение для "стандартной" деятельности, новый экземпляр класса создается реагировать на это намерение. Каждый экземпляр обрабатывает одно намерение. Точно так же новый экземпляр действия "singleTop" также может быть создан для обработки новых намерение. Однако,если целевая задача уже есть существующий экземпляр деятельность в верхней части его стек этот экземпляр получите новое намерение (в onNewIntent() вызов); новый экземпляр не создается.

Я не уверен на 100%, что означает "уже есть существующий экземпляр activity в верхней части его стека", но, возможно, ваша активность не соответствует этому условию.

б singleTask или singleInstance работа для вас? Или, возможно, вы могли бы попробовать установить FLAG_ACTIVITY_SINGLE_TOP о намерении, которое вы создаете чтобы увидеть, если это имеет значение, хотя я не думаю, что это будет.

вы можете вернуться к тому же существующему экземпляру действия с помощью android:launchMode="singleInstance"

в манифесте. Когда вы вернетесь в A С B, может потребоваться finish() уничтожить B.

во первых, структуру стога можно рассмотреть. Для режима запуска:singleTop
Если экземпляр того же действия уже находится в верхней части стека задач, то этот экземпляр будет повторно использоваться для ответа на намерение.

все действия хранятся в стеке ("первый в последний выход"), поэтому, если ваша текущая деятельность находится в верхней части стека и если вы определяете ее в манифесте.файл как singleTop

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

Если вы находитесь в ActivityA воссоздать деятельность он не будет введите onCreate возобновит onNewIntent() и вы можете увидеть, создав уведомление Нет: если вы не реализуете onNewIntent(намерение), вы не получите новое намерение.

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);

        }

Это связано с тем, что исходное действие A уже уничтожается к моменту его запуска из B, C или D. Поэтому onCreate будет вызван вместо onNewIntent(). Один из способов решения этой проблемы-всегда уничтожать существующий a (используя соединение FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK при startActivity) перед запуском нового A, поэтому onCreate всегда будет вызываться, и вы помещаете код onNewIntent() в onCreate, проверяя, является ли getIntent() намерением, которое вы запустили с.