Сохранение состояния приложения 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.

Слово предостережения здесь: Я реализовал этот шаблон, и он работал достаточно хорошо. Однако, похоже, он не слишком хорошо играет в истории, и, наконец, я просто сдался и выдернул этот код. Пока никто не жаловался.

Ответ 3

Для тех, кто придет сюда с подобными проблемами, я нашел что-то странное, возможно, это то, что вы видите... может быть.

Скажем, у меня есть приложение с активностями A → B → C и т.д. У меня возникали проблемы с моим приложением, всегда "возобновляющим" до A, если оно было запущено из списка приложений aka launcher. Возобновление с экрана "resents" (длинное домашнее нажатие) будет демонстрировать правильное поведение возобновления, хотя (возобновляйте до B или C, как ожидалось). Мой манифест не был ничем особенным, у меня всегда всегда установленRetainTaskState = "true" в моем корневом действии, а режим запуска по умолчанию (стандартный).

Я загружал apk на свой телефон через веб-сайт. После загрузки и установки я бы нажал "Открыть" , чтобы сразу запустить приложение. По какой-то причине (после удаления приложения) я устал загружать снова, устанавливая, но затем я нажал кнопку "Готово" вместо. Затем запуск приложения из списка запуска/списка "все приложения" имеет такое же поведение, как и при повторном возвращении - другими словами, мои проблемы были вызваны каким-то образом из-за процесса установки при нажатии "Открыть" вместо "Готово".

Я проверил это "решение" на API10 (2.3.5) и API15 (4.0.4)