Приложение полностью перезагружается при запуске нажатием значка в панели запуска

80

Я пытаюсь создать релизную сборку своего первого приложения для Android, чтобы отправить ее нескольким тестерам. Однако у меня возникла проблема. Когда вы выходите из приложения, а затем повторно входите в него, запустив его с помощью значка, оно перезапускает все приложение вместо возврата в предыдущее место. Это происходит, даже если вы снова войдете сразу после выхода. Однако этого не происходит, если я удерживаю кнопку «Домой» и запускаю ее через список последних приложений.

Я искал в Интернете других людей, у которых есть эта проблема, и их несколько, но ни у кого никогда не было твердого ответа, почему с ними это происходит. В старых вопросах предлагалось установить режим запуска на одиночную задачу или одиночный экземпляр в файле манифеста, но это мне не помогло, и кроме того - насколько я понимаю, поведение по умолчанию для Android - вернуться к предыдущему состоянию задачи. в этой ситуации, поэтому я не знаю, зачем мне нужны специальные параметры манифеста, чтобы заставить его это сделать.

Самая странная вещь в этой проблеме заключается в том, что если я использую eclipse и отладчик для установки приложения на свой телефон, эта проблема не возникает. Мне даже не нужно подключаться к отладчику, похоже, пока у меня есть отладочная версия приложения, проблема не возникает. Но если я использую релизную версию (я создаю ее с помощью пункта меню Android Tools - Export Signed Application Package в Eclipse), возникает проблема. Если у кого-нибудь есть понимание того, что вызывает это, я хотел бы услышать ваши мысли.

LayfieldK
источник
2
Очевидно, если я перезапущу устройство, на котором я устанавливаю приложение, эта проблема исчезнет. Это круто и все такое, но в случае с моим приложением пользователям все равно будет очень неприятно, если оно будет вести себя таким образом до перезагрузки телефона, когда они его загрузят.
LayfieldK
Можете ли вы предоставить трассировку стека или журнал?
TryTryAgain
2
Нет, это происходит только тогда, когда я использую релизную версию приложения, поэтому у меня нет трассировки стека или журнала.
LayfieldK
3
У меня была такая же проблема, вы когда-нибудь узнали, как исправить? или причина? или даже иметь возможность воссоздать поведение после перезапуска устройства? - кстати, я также обнаружил, что принудительная остановка приложения очищает поведение
kassim
2
Правильный ответ на эту проблему можно найти здесь: stackoverflow.com/questions/19545889/…
Mythul

Ответы:

59

У меня была та же проблема с приложением , и я решил это поведение , добавив флаг "android:launchMode="singleTop""вместо "android:launchMode="singleTask""в <activity>объявлении файла AndroidManifest.xml. Надеюсь, это кому-нибудь поможет.

небо
источник
3
Этот подход опасен, если мы хотим дважды открыть одно и то же действие с разными данными.
hkaraoglu 08
6
Если вы хотите открыть одно и то же действие с разными данными, вы можете обработать это в onNewIntent ().
Тас
Я также обнаружил, что если я просто удаляю android:launchModeатрибут, он полностью работает. Не уверен, что он по умолчанию "стандартный", но любые идеи были бы полезны. Я нашел это отличное объяснение, но уже поздно, поэтому сейчас оно кажется мне иностранным: inthecheesefactory.com/blog/…
Джошуа Пинтер,
Привет, я могу добавить android: launchMode = "singleTop" ко всем моим действиям ?.
jmarkstar
В моем случае это не сработало. В моем приложении у меня есть возможность создавать и делиться ссылкой на что-то. Если приложение находится в фоновом режиме и если пользователь щелкает общую ссылку, он открывает полностью новый экземпляр приложения, если для моего launchMode установлено значение «singleTop» или «singleInstance».
tech_human
33

Пока что я выяснил, что это проблема, связанная с тем, как вы устанавливаете ее на свое реальное устройство, а именно:

  1. Если вы просто скопируете и вставите APK-файл в локальное хранилище своего устройства и установите его с устройства, независимо от того, подписан ли он, не подписан или взят из папки bin, он показывает такое поведение, приложение перезапускается из значка меню.

Если вы установите его с помощью одного из следующих вариантов, эта проблема не появится:

  1. Перейдите в sdk / tools / с помощью терминала или командной строки, затем введите

    adb install <FILE PATH OF .APK FILE>
    

    В Linux введите:

    ./adb install <FILE PATH OF .APK FILE>
    
  2. Просто запустите свой проект из Eclipse.

Я был бы рад узнать, есть ли какой-либо способ распространять правильные APK для бета-тестирования. Я уже пробовал экспортировать подписанный APK, потому что, когда вы копируете и вставляете APK и устанавливаете его вручную, он показывает мошенническое поведение.

Обновить:

Я нашел решение. Выполните эти два шага:

  1. Установите android:launchMode="singleTask" = trueдля всех действий вашего приложения в AndroidMainifest.xml внутри тега активности .
  2. Поместите этот код в свою Launcher Activity onCreate().

    if (!isTaskRoot())
    {
        final Intent intent = getIntent();
        final String intentAction = intent.getAction(); 
        if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
            finish();
            return;       
        }
    }
    

Такое поведение является ошибкой в ​​Android. Не особый случай.

Джаянт Арора
источник
2
Я бы не рекомендовал это. launchMode не следует просто устанавливать. У этого должна быть цель, так как это может вызывать странное поведение (разговоры на основе опыта;))
Мальчик
Если ваше приложение поддерживает такие функции, как блокировка PIN-кода, к нему следует относиться осторожно, когда вы хотите установить android: launchMode = "singleTask".
Логан Гуо,
10

Еще одна странная причина: перезапуск происходит только тогда, когда приложение было запущено нажатием «ОТКРЫТЬ» после копирования на устройство - и - установки.

Тестируйте на OS8.1, не активен режим запуска.

введите описание изображения здесь

суперпользователь
источник
Есть какое-нибудь решение?
Абхай Корадия
7

Вы можете использовать launchMode как singleTop для действия Launcher в AndroidManifest.xml

       <activity
        android:name="<YOUR_ACTIVITY>"
        android:label="@string/app_name"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
васант
источник
5
 // To prevent launching another instance of app on clicking app icon 
        if (!isTaskRoot()
                && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
                && getIntent().getAction() != null
                && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

            finish();
            return;
        }

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

Фатима км
источник
3

Это поведение по умолчанию в Android. Для отладочных сборок он почему-то работает иначе. Это можно решить, добавив android:launchMode="singleInstance"к активности, которую вы хотите перезапустить после запуска с помощью значка.

як32
источник
3

Добавьте это к своему первому занятию:

if (!isTaskRoot()) {
        finish();
        return;
}     
super.onCreate(savedInstanceState);
Боллинг
источник
2
это работает в моем случае, ведьма имеет экран-заставку, который обрабатывает все точки входа в приложение, поэтому, если экран-заставка уже выполнил свою работу и перенаправлен в правильное место в первый раз, нет необходимости делать это снова
Ахмед на
2

Попробуйте использовать, android:alwaysRetainTaskStateкак показано в следующем примере:

<activity
    android:name="com.jsnider.timelineplanner.MainActivity"
    android:alwaysRetainTaskState="true"
    android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
jsnid00
источник
2

Что касается меня, я обнаружил, что ошибочно разместил NoHistory = trueв своем атрибуте активности

[Activity(NoHistory = true, ScreenOrientation = ScreenOrientation.Landscape)]

Это предотвратило возобновление работы приложения и перезапустило его.

Скатерхаз
источник
1

Вы можете попробовать установить android:alwaysRetainTaskState="true"для своей пусковой установки в AndroidManifest.xml.

    <activity
        android:name=".YourMainActivity"
        android:alwaysRetainTaskState="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Подробнее см. Https://developer.android.com/guide/topics/manifest/activity-element.html#always.

Moven
источник
1

Я вижу эту проблему на Android TV в 2019 году. Есть ли лучшее решение? Кроме как

if (!isTaskRoot()) {
    finish();
}

Это работает, но больше похоже на взлом, чем на реальное решение.

Амит
источник
0

Все вышеперечисленные решения не работали одинаково на всех моих устройствах. Он работал на некоторых Samsung, но не на всех.

Причиной проблемы для меня была установка APK вручную.

Альберто М
источник
0

Для меня исправление было добавлено LaunchMode = LaunchMode.SingleTopк моему атрибуту Activity поверх основного действия:

/// <summary>
    /// The main activity of the application.
    /// </summary>
    [Activity(Label = "SilhuettePhone",
        Icon = "@drawable/icon",
        Theme = "@style/MainTheme",
        MainLauncher = true,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
        ScreenOrientation = ScreenOrientation.Portrait,
        LaunchMode = LaunchMode.SingleTop,
        WindowSoftInputMode = SoftInput.AdjustResize)]
Калин Власин
источник
-1

Когда вы нажимаете кнопку «Назад» в Android, onDestroyвызывается метод (в отличие от нажатия кнопки «Домой», когда onPause()вызывается только метод).

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

Золтан
источник
1
Я нажимаю кнопку «Домой», чтобы выйти из приложения.
LayfieldK