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


80

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

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

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


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"к активности, которую вы хотите перезапустить после запуска с помощью значка.


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>

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.


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.