React-native-router-flux: [Android] Back Button closes/crashes app

Created on 13 Jan 2016  路  18Comments  路  Source: aksonov/react-native-router-flux

On Android when I press the back button on the top route, it crashes the app and closes.

Most helpful comment

A better way to handle it:

componentWillMount = () => {
  BackAndroid.addEventListener('hardwareBackPress', () => Actions.pop());
};

All 18 comments

You need to use your BackAndroid Component:

render() {
    BackAndroid.addEventListener('hardwareBackPress', () => {
        try {
            Actions.pop();
            return true;
        }
        catch (err) {
            ToastAndroid.show("Cannot pop. Exiting the app...", ToastAndroid.SHORT);
            return true;
        }
    });

    return (
            <Router hideNavBar={true}>
                <Schema name="modal" sceneConfig={Navigator.SceneConfigs.FloatFromBottom}/>
                <Schema name="default" sceneConfig={Navigator.SceneConfigs.FloatFromBottomAndroid}
.....  
.....

Thanks thats solved it.

A better way to handle it:

componentWillMount = () => {
  BackAndroid.addEventListener('hardwareBackPress', () => Actions.pop());
};

@graywolf336 your solution is good but not perfect, with your solution the app will still close as the 'hardwareBackPress' event expects to get a boolean back saying if the app should remain open or not.
for our luck, the great developers here are returning that boolean in the Actions.pop method. So the entire solution should be:

componentWillMount = () => { BackAndroid.addEventListener('hardwareBackPress', () => return Actions.pop()); };

Your code does the same as mine. ;) one line inline arrow functions return the value without needing the return keyword. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

You're right, didn't notice that :)

i wanna press back button first then display ToastAndroid , and exit app with the second. Help me please

componentWillMount = () => {
BackAndroid.addEventListener('hardwareBackPress', () => { ToastAndroid.show("message",ToastAndroid.SHORT ); setTimeout(()=> { Actions.pop(); } , 1000) );
};

@thanghach I think that should do it 馃構

this is my solution, and i'm success.

componentWillMount() {
BackAndroid.addEventListener('hardwareBackPress', function() {
var _this = this;
if(!this.state.backPress) {
ToastAndroid.show('Back again to exit', ToastAndroid.SHORT);
this.setState({backPress:true});
setTimeout(function() {
_this.setState({backPress:false});
},2500);
} else {
return false;
}
return true;
}.bind(this));
}

Not sure if we should re-open this issue or not @aksonov @graywolf336.

Actions.pop() may return false if you are navigating between tabs.

The React Native BackAndroid (at least in RN 0.42+) module is considering that it should close the app if the register listener is returning false.

Is that the default behaviour we want for the back navigation on tabs?

https://github.com/facebook/react-native/blob/v0.42.0/Libraries/Utilities/BackAndroid.android.js#L36

@BigPun86
@thanghach @JonnyBGod
i have implemented router in the react native app but andoird react native app is getting exit in the back press
i have used this code but in the middle of the app it is also getting exit plz help me out in this

I also have this problem, the solution detailed here does not work.

Using: RN 0.43.2
RNRF: 3.38.0

+1

RN 0.44
BackHandler with onHardwareBackPress event, backbutton press with empty handler closing the app, the app still in background.

Still application is closing

i have added below line in router component
BackAndroid.addEventListener('hardwareBackPress', () => {
try {
Actions.pop();
return true;
}
catch (err) {
ToastAndroid.show("Cannot pop. Exiting the app...", ToastAndroid.SHORT);
return true;
}
});

Main.js

<RouterWithRedux backAndroidHandler={this.handleBack}>

return false will invoke BackAndroid.exitApp(); automatically. return true if you want to not close app.

I added Actions.pop() cause after returning from background my app was failing with exception
There is no route defined for key key1. Must be one of : 'key3'

HandleBackHandler.js

import { ToastAndroid } from 'react-native'
import {Actions} from 'react-native-router-flux'

const ANDROID_TIME_INTERVAL_BACK_BUTTON = 2000
let BACK_BUTTON_PRESSED_ONCE_TO_EXIT = false

const hwBackButtonHandler = () => {
  if (BACK_BUTTON_PRESSED_ONCE_TO_EXIT) {
    Actions.pop()
    return false
  }

  BACK_BUTTON_PRESSED_ONCE_TO_EXIT = true
  ToastAndroid.show('Please tap BACK again to exit app', ToastAndroid.SHORT)

  setTimeout(() => {
    BACK_BUTTON_PRESSED_ONCE_TO_EXIT = false
  }, ANDROID_TIME_INTERVAL_BACK_BUTTON)

  return true
}

export default hwBackButtonHandler

Hi all, Where should I add this code
componentWillMount = () => {
BackAndroid.addEventListener('hardwareBackPress', () => Actions.pop());
};

Was this page helpful?
0 / 5 - 0 ratings