React Native Android, несколько экземпляров приложений, запущенных одновременно в результате выхода из фонового состояния без предварительного закрытия приложения.

Ниже описан процесс воспроизведения ошибки.

Это происходит в моем проекте v0.29, но я только что протестировал новый на v0.33, и он ведет себя так же.

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

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

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

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

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

Таким же образом, если вы реализуете такой пакет, как react-native-activity-android, чтобы избежать уничтожения приложения при нажатии кнопки «Назад», вы получите несколько запущенных приложений.

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

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

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

Любые идеи, как решить эту проблему, поэтому отправка приложения в фоновый режим и его повторное открытие не монтирует несколько приложений?

В случае, если мне нужно, чтобы приложение работало в фоновом режиме для целей определения местоположения/уведомления, предположим, что я не могу решить эту проблему, но я могу обрабатывать прослушиватели событий, чтобы они не выполнялись несколько раз. Насколько плохо для производительности/памяти одновременное подключение нескольких приложений?

Спасибо


person Norber S.M    schedule 23.09.2016    source источник


Ответы (3)


Эта ошибка связана с тем, что React Native создает более одной активности для каждого приложения, что приводит к одновременному запуску нескольких корневых компонентов.

Решение, которое работает для большинства людей, состоит в том, чтобы установить launchMode в singleInstance в AndroidManifest.xml, что-то вроде этого:

<manifest>
    ...
    <application>
        ...
        <activity ... android:launchMode="singleInstance">
        </activity>
    </application>
</manifest>

Больше информации там:

https://github.com/facebook/react-native/issues/10266

https://github.com/facebook/react-native/issues/7079

person laurent    schedule 09.07.2017
comment
происходит для меня на IOS, а не на Android - person n0rd; 24.08.2020

Оказывается, использование BackAndroid и возврат false из обработчика обратного нажатия приводит к размонтированию компонентов. Эти компоненты необходимо перестроить, когда приложение вернется на передний план.

Я пытался добавить android:launchMode="singleTask" к активности в AndroidManifest.xml безрезультатно. Мое решение состояло в том, чтобы использовать react-native-activity-android, поставить приложение в фоновом режиме с ActivityAndroid.moveTaskToBack() по мере необходимости и никогда return false. Тогда ваш обработчик будет выглядеть примерно так:

handleBackPress() {
    if (this.navigator) {
        if (this.navigator.getCurrentRoutes().length > 1) {
            this.navigator.pop();
        } else {
            ActivityAndroid.moveTaskToBack();
        }
    }
    return true;
};

ПРИМЕЧАНИЕ. Автор этого плагина еще не обновил его для совместимости с React Native 0.29.0 или выше. Мой запрос на извлечение, чтобы исправить это, находится на рассмотрении в настоящее время это письмо.

person Ryan H.    schedule 04.01.2017

На самом деле, вы можете реализовать свой собственный модуль, чтобы решить эту проблему. Это довольно просто. Добавьте этот фрагмент кода в один из ваших нативных модулей.

@ReactMethod
public void moveTaskToBack(Callback cb) {
    Activity activity = getCurrentActivity();
    boolean wasMoved = activity.moveTaskToBack(true);
    if (cb != null) {
        cb.invoke(wasMoved);
    }
}

Затем вы можете обработать событие onBackPress, как предложил Райан. Всегда возвращайте true и вызывайте moveTaskToBack() при необходимости.

person Hubert Wang    schedule 17.03.2017