Проблема упорядочения стека активности при запуске приложения из установщика приложения Android и с главного экрана - PullRequest
50 голосов
/ 15 июня 2011

Только для целей тестирования, я разрешаю загружать и устанавливать APK моего приложения через URL. После загрузки на телефон его можно запустить с помощью установщика приложений Android, который дает пользователю возможность установить его на свое устройство, а затем запустить.

Подумайте, загрузили ли мы и запустили ли приложение способом, описанным выше. Основной / запускаемой активностью в моем приложении является страница входа (Activity A). Как только пользователь аутентифицирован, он попадает в основную область приложения, например, Activity B. Так что теперь текущий стек активности этой задачи A > B.

Затем я нажимаю кнопку «Домой» на телефоне и перехожу на домашний экран Android. Я перезапускаю свое приложение через значок в меню, и меня перенаправляют на Activity A вместо Activity B. Либо стек активности теперь A > B > A, либо теперь есть две отдельные задачи со стеками активности A > B и A соответственно. Я хочу вернуться к Activity B при перезапуске приложения. Повторное нажатие в этом состоянии вернет меня к Activity B.

Это нежелательное поведение происходит, только если я сначала открываю приложение через установщик, а не если я открываю приложение через домашний экран / меню.

Я смотрел, как действия запускаются каждым механизмом. Когда мы используем установщик приложения, мы видим следующие журналы:

INFO/ActivityManager(XXXX): Starting activity: Intent { dat=file:///mnt/sdcard/download/[my app].apk cmp=com.android.packageinstaller/.InstallAppProgress (has extras) }
INFO/ActivityManager(XXXX): Starting activity: Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=[my package]/[Activity A] }

через панель запуска / домашний экран:

INFO/ActivityManager(XXXX): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=[my package]/[Activity A] }

При запуске с установщиком мы видим, что он использует флаг 0x10000000, но при запуске с помощью программы запуска мы видим, что он использует 0x10200000. Также используется категория намерений.

Из документов мы видим флаги:

public static final int FLAG_ACTIVITY_NEW_TASK
Constant Value: 268435456 (0x10000000)

public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
Constant Value: 2097152 (0x00200000)

Флаг FLAG_ACTIVITY_RESET_TASK_IF_NEEDED (который используется, когда приложение запускается из модуля запуска), как правило, препятствует созданию новой задачи, если она уже существует, и восстанавливает последнее использованное действие. Это желаемое поведение. Почему это не работает в этой ситуации? Могу ли я что-нибудь сделать, чтобы мое приложение всегда возвращало меня к последнему действию, независимо от того, было ли оно запущено через установщик / панель запуска приложения?

Если я использую singleTask, это всегда возвращает меня к основному виду деятельности (Activity A) всякий раз, когда я запускаю приложение (что также нежелательно).

Вот вопрос, который я нашел, когда кто-то испытывает похожую проблему (на которую нет принятого ответа): Приложение теряет способность запоминать свой стек при запуске из другого приложения

РЕДАКТИРОВАТЬ: проверка на флаг FLAG_ACTIVITY_BROUGHT_TO_FRONT в onCreate() нашего действия по запуску (и затем завершение, если оно установлено), похоже, устраняет основной симптом, но очевидно, что основная проблема все еще существует. Есть ли более полное исправление?

EDIT2: тот же результат возникает при загрузке / запуске приложения из Android Market, поэтому некоторые из приведенных выше сведений могут быть неактуальными.

Ответы [ 3 ]

30 голосов
/ 28 июля 2011

Добавлен ответ, предоставленный антонитом:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
        // Activity was brought to front and not created,
        // Thus finishing this will get us to the last viewed activity
        finish();
        return;
    }

    // Regular activity creation code...
}
12 голосов
/ 18 июня 2011

Основная проблема, которую я считаю, состоит в том, что используемые Intent различаются между лаунчером и установщиком.Поскольку вы получаете разные флаги Intent, вы будете получать другое поведение при запуске.Вы можете испортить режимы запуска, и вы сможете получить последовательный результат, но в основном эти разные Intents будут давать разные результаты.

Ваше исправление (или что-то вроде this ), вероятно, вашеЛучшая ставка.

0 голосов
/ 22 июня 2011

Ваша проблема, вероятно, коренится в том факте, что установщик приложения не использует категорию LAUNCHER, как и модуль запуска.

Эта ошибка была задокументирована в другом месте:

Приложение всегда запускается заново из корневой активности вместо возобновления фонового состояния (Известная ошибка)

...