Режим запуска «single top» для Android и onNewIntent

Я прочитал в документации для Android, что, установив свойство launchMode моей Activity в singleTop OR, добавив флаг FLAG_ACTIVITY_SINGLE_TOP в свой Intent, вызов вызывающего startActivity(intent) будет использовать один экземпляр Activity и дать мне Intent в onNewIntent . Я делал обе эти вещи, и onNewIntent никогда не срабатывает и не onCreate огонь каждый раз. Документы также говорят, что this.getIntent() возвращает намерение, которое было сначала передано в Activity, когда оно было впервые создано. В onCreate я getIntent и каждый раз получаю новый (я создаю объект намерения в другом действии и добавляю дополнительный ему), этот дополнительный должен быть одинаковым каждый раз, если он возвращает меня тот же объект намерения). Все это заставляет меня поверить, что моя деятельность не действует как «единственная вершина», и я не понимаю, почему.

Чтобы добавить некоторый фон, если я просто пропустил необходимый шаг, вот объявление активности в манифесте и код, который я использую для запуска этой операции. Сама деятельность не делает ничего достойного упоминания в отношении этого:

в AndroidManifest.xml:

    

в моей вызывающей деятельности:

  Intent i = new Intent(); i.putExtra(EXTRA_KEY_ARTIST, id); i.setClass(this, ArtistActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(i); 

Вы проверяли, onDestroy() ли onDestroy() ? Вероятно, поэтому onCreate() вызывается каждый раз вместо onNewIntent() , который вызывается только в том случае, если активность уже существует.

Например, если вы покинете свою деятельность с помощью кнопки BACK, она по умолчанию будет уничтожена. Но если вы поднимаетесь выше в стеке действий в другие действия и оттуда снова вызываете свой ArtistActivity.class он будет пропускать onCreate() и перейти непосредственно к onNewIntent() , потому что эта активность уже создана, и поскольку вы определили ее как singleTop Android не будет создавать новый экземпляр, но возьмите тот, который уже лежит.

Что я делаю, чтобы посмотреть, что происходит Я реализую фиктивные функции для всех разных состояний каждого вида деятельности, поэтому я всегда делаю то, что происходит:

 @Override public void onDestroy() { Log.i(TAG, "onDestroy()"); super.onDestroy(); } 

То же самое для onRestart() , onStart() , onResume() , onPause() , onDestroy()

Если вышеупомянутая (кнопка BACK) не была вашей проблемой, реализация этих макетов, по крайней мере, поможет вам немного отладить ее.

Принятый ответ не совсем корректен. Если onDestroy () был вызван ранее, тогда да, onCreate () всегда будет вызываться. Однако это утверждение неверно : «Если вы поднимаетесь выше в стеке действий в другие действия и оттуда снова вызываете свой ArtistActivity.class, он будет пропускать onCreate () и перейти непосредственно к onNewIntent ()»

Раздел «singleTop» в http://developer.android.com/guide/components/tasks-and-back-stack.html объясняет, как это работает (внимание к жирным текстам ниже, я также доказал это через свои собственные отладка):

Например, предположим, что стоп-память задачи состоит из корневой активности A с действиями B, C и D сверху ( стек ABCD; D сверху ). Умысел прибывает для действия типа D. Если D имеет стандартный «стандартный» режим запуска, запускается новый экземпляр classа, и стек становится ABCDD. Однако если режим запуска D «singleTop», существующий экземпляр D получает намерение через onNewIntent (), потому что он находится наверху стек – стек остается ABCD. Однако, если намерение прибывает для активности типа B, то в стек добавляется новый экземпляр B, даже если его режим запуска «singleTop» ».

Другими словами, запуск активности через SINGLE_TOP будет только повторно использовать существующее действие, если оно уже находится в верхней части стека . Он не будет работать, если другое действие в той же самой задаче находится наверху (например, действие, выполняющее startActivity (SINGLE_TOP)); вместо этого будет создан новый экземпляр.

Вот два способа исправить это, чтобы вы получили поведение SINGLE_TOP, которое вы хотите – общая цель которого заключается в повторном использовании существующего действия вместо создания нового …

Первый способ (как описано в разделе комментариев принятого ответа): вы можете добавить в свою активность startMode «singleTask». Это заставит onNewIntent (), потому что singleTask означает, что может быть только один экземпляр определенного действия в заданной задаче. Это несколько хакерское решение, потому что, если вашему приложению требуется несколько экземпляров этой активности в конкретной ситуации (например, я делаю для своего проекта), вы ввернуты.

Второй способ (лучше): вместо FLAG_ACTIVITY_SINGLE_TOP используйте FLAG_ACTIVITY_REORDER_TO_FRONT. Это приведет к повторному использованию существующего экземпляра активности, переместив его в начало стека (onNewIntent () будет вызываться как ожидалось).

Основной целью FLAG_ACTIVITY_SINGLE_TOP является предотrotation создания нескольких экземпляров Activity. Например, когда эта деятельность может быть запущена с помощью намерения, которое происходит из-за основной задачи вашего приложения. Для внутреннего переключения между действиями в моем приложении я обнаружил, что FLAG_ACTIVITY_REORDER_TO_FRONT – это вообще то, что я хочу.

Установите этот флаг в соответствии с вашими намерениями:

 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP) 
  • Как основной stream, созданный Java
  • Можно ли читать данные Firebase без подключения слушателей?
  • Активность Android ClassNotFoundException - все
  • как проверить Wi-Fi или 3g-сеть доступна на Android-устройстве
  • Как использовать интерфейс для связи между двумя действиями
  • Проверка сертификатов X509 с использованием Java APis
  • Как преобразовать целое число цвета в шестнадцатеричную строку в Android?
  • Ошибка AndroidRuntime: Посылка: не удалось вывести значение маршала
  • IntelliJ IDEA с Junit 4.7 "!!! Ожидается, что версия JUnit версии 3.8 или более поздняя:
  • Как исправить android.os.NetworkOnMainThreadException?
  • Java: ошибка: переменная не была инициализирована
  • Interesting Posts

    Двойной загрузочный компьютер: окна 7 часов становятся неправильными после загрузки Linux

    В SQL, как выбрать верхние 2 строки для каждой группы

    Как определить завершенный процесс Windows, если у меня все еще есть его PID?

    Почему Python 3.6.1 выбрасывает AttributeError: модуль ‘enum’ не имеет атрибута ‘IntFlag’?

    Вопрос о прекращении streamа в .NET.

    Передача массива данных в качестве входного параметра в процедуру Oracle

    Windows 10 запуталась (bad_system_config)

    Почему статические методы classа унаследованы, но не статические методы интерфейса?

    Как заставить скрипт запускаться при запуске машины Ubuntu?

    Twitter Bootstrap – как центрировать элементы по горизонтали или по вертикали

    Как я могу исключить несколько папок с помощью Get-ChildItem -exclude?

    Место для размещения Database.SetInitializer

    На локальном хосте, как мне выбрать номер порта?

    Произошел сбой Windows 10

    Связывание нескольких параметров с запросом mysqli

    Давайте будем гением компьютера.