Почему происходит сбой моего приложения React Native для Android при закрытии или нажатии кнопки «Назад»? - PullRequest
1 голос
/ 03 июля 2019

Приложение My React Native для Android падает при закрытии приложения или нажатии кнопки «Назад». Похоже, если приложение завершает работу с помощью кнопки «Назад» или нет, оно сообщает о сбое.

Я искал много похожих проблем и решений, и ни один из них не помог мне.

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

Я попробовал «response-native-exit-app», которое, очевидно, должно закрывать приложение, не вызывая уведомления о сбое, но это не работает. Он по-прежнему сообщает о сбое при выходе.

Я пробовал BackHandler.exitApp (), но это также приводит к аварийному завершению работы приложения.

Я использую React Navigation и вижу кнопку «Назад», которая управляет маршрутами. Я подумал, что это может быть причиной проблемы, поэтому я попытался отключить это. Поэтому нет кнопки «Назад» для управления маршрутами. Мне удалось отключить его, но я не уверен, что все сделано правильно. Несмотря на это, это не помогло, так как приложение по-прежнему зависало при возврате или выходе.

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

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

Когда приложение аварийно завершает работу, оно не говорит ничего полезного в журналах. Просто есть одна строка, которая не является конкретной.

Я немного застрял сейчас. Я вижу множество сообщений о сбоях в Play Store. Я знаю, что это люди, которые нажимают кнопку «Назад», а затем снова открывают приложение. Мне нужно найти решение, но я все перепробовал и не повезло.

Есть идеи?

--- КОД

import { BackHandler, ToastAndroid } from 'react-native';

constructor(properties) {
  super(properties);

  this.handleBackButton = this.handleBackButton.bind(this);
}

componentWillMount() {
  BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}

componentWillUnmount() {
  BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}

handleBackButton = () => {
  console.log('Android hardware back button pressed!');
  ToastAndroid.show('Exiting the app...', ToastAndroid.SHORT);
  BackHandler.exitApp();
  return true;
}

- LOG

07-04 12:13:50.893 10849 10904 I ReactNativeJS: Android hardware back button pressed!
07-04 12:13:50.895 10849 10904 I ReactNativeJS: Android hardware back button pressed!
07-04 12:13:50.948 10849 10904 I ReactNativeJS: 'appState', 'background'
07-04 12:13:51.641 10849 10849 D ReactNative: ReactInstanceManager.detachViewFromInstance()   <---   this is all I see when it crashes

- ОБНОВЛЕНИЕ

Мне удалось заставить трассировку стека работать так ...

cd android
./gradlew installDebug --stacktrace
cd ..
react-native log-android

Похоже, что Firebase - это то, что вылетает ...

07-04 13:55:55.362 13517 13574 W ReactNativeJS: Overwriting FirebaseError base field "name" can cause unexpected behavior.
07-04 13:55:55.434 13517 13574 W ReactNativeJS: Overwriting FirebaseError base field "name" can cause unexpected behavior.
07-04 13:55:55.493 13517 13574 E ReactNativeJS: [DEFAULT]: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).
07-04 13:55:55.493 13517 13574 E ReactNativeJS: 
07-04 13:55:55.493 13517 13574 E ReactNativeJS: This error is located at:
07-04 13:55:55.493 13517 13574 E ReactNativeJS:     in Wrapper (at renderApplication.js:35)
07-04 13:55:55.493 13517 13574 E ReactNativeJS:     in RCTView (at View.js:45)
07-04 13:55:55.493 13517 13574 E ReactNativeJS:     in View (at AppContainer.js:98)
07-04 13:55:55.493 13517 13574 E ReactNativeJS:     in RCTView (at View.js:45)
07-04 13:55:55.493 13517 13574 E ReactNativeJS:     in View (at AppContainer.js:115)
07-04 13:55:55.493 13517 13574 E ReactNativeJS:     in AppContainer (at renderApplication.js:34)
07-04 13:55:55.550 13517 13574 E ReactNativeJS: [DEFAULT]: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).

--- решено!

Проверка трассировки стека была действительно полезной. Как только я начал работать, я увидел, что проблема возникла из-за Firebase.

Я решил проблему следующим образом:

if (!firebase.apps.length) {
  firebase.initializeApp({
    ...
  });
}

1 Ответ

0 голосов
/ 04 июля 2019

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

componentDidMount() {
    this.backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
        if (!this.shouldBeAppClosed()) {
            this.yourBackButtonFunction();
            return true;
        }
        return false;
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}
...