Сохранение состояния приложения Android с использованием alwaysRetainTaskState и lauchMode
В моем приложении для Android у меня есть основное действие, которое служит точкой входа в мое приложение, которое настроено в моем файле манифеста следующим образом:
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Итак, для конкретного примера использования пользователь может запустить приложение с главного экрана, щелкнув значок в панели запуска приложения. После запуска приложения пользователь переходит от основной деятельности к активности A, а затем, наконец, к активности B. На этом этапе пользователь решает проверить свою facebook, поэтому они нажимают кнопку "домой", чтобы положить мое приложение в фоновом режиме, и запускает приложение facebook.
После проверки своей facebook пользователь хочет вернуться в мое приложение, поэтому они нажимают домашний ключ и запускают приложение из панели запуска приложения (как и в первый раз, когда он был запущен).
Когда пользователь вернется в мое приложение, я хочу, чтобы приложение вернулось к последнему действию, которое было у пользователя, когда приложение было помещено в фоновое изображение, которое в этом случае является активностью B. В файле манифеста я установил alwaysRetainTaskState = true, чтобы убедиться, что ОС не убивает мои действия приложения.
Теперь на мой вопрос: как мне получить описанное выше поведение? Всякий раз, когда я нажимаю значок своего приложения, он всегда начинается с основной деятельности, несмотря ни на что. Я думаю, это из-за атрибута category.LAUNCHER. Я пробовал Android: launchMode = singleTask, но это не изменило; он всегда начинается с Main.
Если кто-то может прояснить фильтры намерений, режимы запуска и задачи, это будет здорово!
Ответы
Ответ 1
Я решил это, добавив экранный DispatcherActivity
и сделав его по умолчанию (используя тот же фильтр намерений). В своем методе onCreate
вы создаете и вызываете намерение на основе некоторого разумного значения по умолчанию (например, основной деятельности) ИЛИ на основе некоторого сохраненного токена, который идентифицирует, какая активность должна быть запущена. Этот токен сохраняется/обновляется в onStop
методе любой операции, которую вы хотите вызвать при перезапуске. Вы можете сохранить этот токен в настройках.
Рациональным здесь является то, что последняя активность, которая была видима, будет прервана при использовании метода onStop.
Слово предостережения здесь: Я реализовал этот шаблон, и он работал достаточно хорошо. Однако, похоже, он не слишком хорошо играет в истории, и, наконец, я просто сдался и выдернул этот код. Пока никто не жаловался.
Ответ 2
FYI singleTask
- это не то, что вы хотите, так как оно запускает новую задачу:
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Как вы запускаете Activity B? Любые нестандартные режимы запуска или флаги Intent?
Ответ 3
Для тех, кто придет сюда с подобными проблемами, я нашел что-то странное, возможно, это то, что вы видите... может быть.
Скажем, у меня есть приложение с активностями A → B → C и т.д. У меня возникали проблемы с моим приложением, всегда "возобновляющим" до A, если оно было запущено из списка приложений aka launcher. Возобновление с экрана "resents" (длинное домашнее нажатие) будет демонстрировать правильное поведение возобновления, хотя (возобновляйте до B или C, как ожидалось). Мой манифест не был ничем особенным, у меня всегда всегда установленRetainTaskState = "true" в моем корневом действии, а режим запуска по умолчанию (стандартный).
Я загружал apk на свой телефон через веб-сайт. После загрузки и установки я бы нажал "Открыть" , чтобы сразу запустить приложение. По какой-то причине (после удаления приложения) я устал загружать снова, устанавливая, но затем я нажал кнопку "Готово" вместо. Затем запуск приложения из списка запуска/списка "все приложения" имеет такое же поведение, как и при повторном возвращении - другими словами, мои проблемы были вызваны каким-то образом из-за процесса установки при нажатии "Открыть" вместо "Готово".
Я проверил это "решение" на API10 (2.3.5) и API15 (4.0.4)