Приложение теряет способность запоминать свой стек при запуске из другого приложения - PullRequest
9 голосов
/ 16 марта 2011

Теперь, когда я исследовал это еще больше, я переписываю это, чтобы сделать его более понятным. Если вам нужна дополнительная информация, в старых редакциях есть информация.

Что происходит:

(Это относится к приложению, которое не установило никакой launchMode настройки и т. д. использует значения по умолчанию)

  1. Вы запускаете приложение из Маркета или из Установщика. это запускает основную / основную активность приложения с Флаг FLAG_ACTIVITY_NEW_TASK и без категорий. Сейчас стек приложений [A]

  2. Затем вы переходите к следующему действию в приложении. Теперь стек в этой задаче [A> B]

  3. Затем вы нажимаете клавишу возврата и затем запускаете то же самое приложение. нажав на значок на главном экране или в панели приложений.

  4. В этот момент ожидается, что активность B покажет, так как это то, где вы остановились. Однако отображается A, а стек задач [A> B> A] Этот второй экземпляр A запускается с следующие флаги: FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_RESET_IF_NEEDED и FLAG_ACTIVITY_BROUGHT_TO_FRONT. Это также имеется категория android.intent.category.LAUNCHER.

В этот момент, если вы нажмете клавишу возврата, он вернет вас к B, так как был когда ты это оставил.

Глядя на документацию, кажется, что FLAG_ACTIVITY_BROUGHT_TO_FRONT следует устанавливать только для действий, которые используйте режимы запуска SingleTask или SingleTop. Тем не менее, это приложение не установило никаких launchModes и поэтому использует стандартный режим запуска по умолчанию.

Я полагаю, этого не произойдет в этом случае?

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

Итак, в общем, почему это происходит? Есть ли способ предотвратить это?

Ответы [ 2 ]

3 голосов
/ 16 марта 2011

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

Пожалуйста, дайте мне знать, если вы видите в этом какие-либо дыры.

В методе onCreate основного / корневого действия проверьте, установлено ли в намерении FLAG_ACTIVITY_BROUGHT_TO_FRONT и, если это так, вызовите finish ().Это затем выталкивает дополнительный экземпляр A из стека [A> B> A] становится [A> B] и с точки зрения пользователей запускается в действие, которое они ожидали.

Кажется, что работает ввсе мои тесты до сих пор.Мое единственное беспокойство заключается в том, что если есть какой-то странный случай, когда кто-то запускает, всегда будет отмечать запуск с FLAG_ACTIVITY_BROUGHT_TO_FRONT, даже если приложение еще не было в задаче, и, следовательно, полностью заблокирует их, потому что оно будет вызывать finish () и не иметьчто-либо в стеке, к которому нужно вернуться.

-

В соответствии с просьбой в комментариях, вот как вы можете проверить, является ли намерение определенным флагом:

int flags = intent.getFlags();
boolean hasFlag = flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT == Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT;

--

Также я должен отметить, что я все еще вижу, что эта проблема иногда возникает с этим исправлением на месте.Это не кажется идеальным решением.

0 голосов
/ 16 марта 2011

Переопределение onConfigurationChanged () должно помочь вам сохранить состояние.

http://developer.android.com/reference/android/app/Activity.html

Изменения конфигурации

Если изменяется конфигурация устройства (как определено классом Resources.Configuration), то все, что отображаетсяпользовательский интерфейс должен будет обновить, чтобы соответствовать этой конфигурации.Поскольку Activity является основным механизмом взаимодействия с пользователем, он включает специальную поддержку для обработки изменений конфигурации.

Если не указано иное, изменение конфигурации (например, изменение ориентации экрана, языка, устройств ввода и т. Д.) приведет к тому, что ваша текущая активность будет уничтожена, пройдя нормальный процесс жизненного цикла активности onPause (), onStop () и onDestroy () в зависимости от ситуации.Если действие находилось на переднем плане или было видимым для пользователя, при вызове onDestroy () в этом экземпляре будет создан новый экземпляр действия, с любым сохраненным значением InstanceState, сгенерированным предыдущим экземпляром из onSaveInstanceState (Bundle).*

Это сделано потому, что любой ресурс приложения, включая файлы макетов, может меняться в зависимости от любого значения конфигурации.Таким образом, единственный безопасный способ обработки изменения конфигурации - это повторное извлечение всех ресурсов, включая макеты, графические объекты и строки.Поскольку действия уже должны знать, как сохранить свое состояние и воссоздать себя из этого состояния, это удобный способ перезапустить действие с новой конфигурацией.

В некоторых особых случаях может потребоватьсяобойти перезапуск вашей деятельности на основе одного или нескольких типов изменений конфигурации.Это делается с помощью атрибута android: configChanges в его манифесте.Для любых типов изменений конфигурации, которые, как вы говорите, вы обрабатываете там, вы будете получать вызов метода onConfigurationChanged (Configuration) вашего текущего действия, а не перезапускаться.Если изменение конфигурации включает в себя любое, которое вы не обрабатываете, однако, действие все равно будет перезапущено и onConfigurationChanged (Configuration) не будет вызываться. "

...