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


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.