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

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

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

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

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

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

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

Ответы [ 6 ]

68 голосов
/ 11 марта 2010

Это должно сработать.

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

Когда вы создаете намерение запустить приложение, используйте:

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

Это то, что нужно.

29 голосов
/ 11 марта 2010

В конце концов, у меня получилось так:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
14 голосов
/ 11 марта 2010

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

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

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

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

6 голосов
/ 31 мая 2012

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

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

1 голос
/ 01 декабря 2014

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

Все действия удерживаются в стеке («первым пришел последним»), поэтому, если ваша текущая активность находится на вершине стека и если вы определили ее в manifest.file как 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);

        }
0 голосов
/ 21 июля 2015

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

...