Додаток повністю перезавантажується при запуску натисканням значка в панелі запуску


80

Я намагаюся створити реліз своєї першої програми для Android, яку потрібно надіслати кільком тестувальникам. Однак я зіткнувся з проблемою. Коли ви виходите з програми, а потім знову вводите її, запускаючи через її піктограму, вона перезапускає всю програму, а не повертається до попереднього місця. Це відбувається, навіть якщо ви знову входите відразу після виходу. Однак це не трапляється, якщо я утримую кнопку головного екрана та запускаю її через останній список програм.

Я шукав в Інтернеті інших, хто має цю проблему, і їх є декілька, але ніхто ніколи не мав твердої відповіді, чому це з ними відбувається. У старих запитаннях пропонувалося встановити для режиму запуску значення singletask або singleinstance у файлі маніфесту, але це мені не допомогло, і крім того - з того, що я розумію, поведінка за замовчуванням для android - це повернення до попереднього стану завдання у цій ситуації, тому я не знаю, навіщо мені потрібні спеціальні варіанти маніфесту, щоб зробити це.

Найбільш химерне в цій проблемі полягає в тому, що якщо я використовую eclipse та налагоджувач, щоб розмістити програму на своєму телефоні, ця проблема не виникає. Мені навіть не потрібно підключатися до налагоджувача, здається, що поки у мене є налагоджувальна версія програми, проблема не виникає. Але якщо я використовую випускну версію (я створюю її за допомогою інструментів Android - параметр меню Експорт підписаного додатка в Eclipse), проблема трапляється. Якщо хтось має уявлення про те, що це спричиняє, я хотів би почути ваші думки.


2
Отож, очевидно, якщо я перезавантажую пристрій, на якому інсталюю програму, ця проблема перестає існувати. Зараз це круто, і все, але у випадку мого додатка це все одно буде надзвичайно дратувати користувачів, якщо він буде поводитися так перед перезапуском телефону, коли вони завантажать його.
— LayfieldK

Чи можете ви надати стек або журнал?
— TryTryAgain

2
Ні, це трапляється лише тоді, коли я використовую випускну версію програми, тому у мене немає стека або журналу.
— LayfieldK

3
У мене була та сама проблема, чи дізнавались ви коли-небудь виправлення? чи причина? або навіть мати можливість відтворити поведінку після перезапуску пристрою? - До речі, я також виявив, що примусове зупинення програми очищає поведінку
— Кассім

2
Дійсний відповідь на це питання можна знайти тут: stackoverflow.com/questions/19545889 / ...
— Mythul

Відповіді:


59

У мене була та сама проблема з додатком, і я вирішив цю поведінку, додаючи прапор, "android:launchMode="singleTop""а не "android:launchMode="singleTask""в <activity>декларації вашого файлу AndroidManifest.xml. Сподіваюся, це комусь допоможе.


3
Цей підхід небезпечний, якщо ми хочемо відкрити одну і ту ж діяльність двічі з різними даними.
— hkaraoglu

6
Якщо ви хочете відкрити одну і ту ж діяльність з різними даними, ви можете впоратися з цим у onNewIntent ().
— Тас

Я також виявив, що якщо я просто видаляю android:launchModeатрибут повністю, він працював. Не впевнений, що за замовчуванням він має значення "стандартний", але будь-які ідеї були б корисними. Я знайшов це чудове пояснення, але вже пізно, тому мені зараз здається іноземною мовою: inthecheesefactory.com/blog/…
— Джошуа Пінтер,

Привіт, чи варто додати андроїд: 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

Ще одна дивна причина - перезапуск відбувається лише тоді, коли додаток було запущено, натиснувши кнопку "ВІДКРИТИ" після Copy-to-Device - & - Install.

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

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


Є якесь рішення?
— Абхай Корадія

7

Ви можете використовувати launchMode як singleTop для Launcher Activity в 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.