diff --git a/Examples/UIExplorer/BackAndroidExample.js b/Examples/UIExplorer/BackAndroidExample.js
new file mode 100644
index 000000000..3643f76f6
--- /dev/null
+++ b/Examples/UIExplorer/BackAndroidExample.js
@@ -0,0 +1,66 @@
+/**
+ * The examples provided by Facebook are for non-commercial testing and
+ * evaluation purposes only.
+ *
+ * Facebook reserves all rights not expressly granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
+ * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+'use strict';
+
+var React = require('react-native');
+var {
+ Text,
+ View,
+ BackAndroid,
+} = React;
+
+var BackAndroidExample = React.createClass({
+
+ getInitialState: function() {
+ return {
+ defaultBackHandler: false
+ };
+ },
+
+ componentDidMount: function() {
+ BackAndroid.addEventListener('hardwareBackPress', this._handleBackButton);
+ },
+
+ componentWillUnmount: function() {
+ BackAndroid.removeEventListener('hardwareBackPress', this._handleBackButton);
+ },
+
+ _handleBackButton: function() {
+ if (!this.state.defaultBackHandler) {
+ this.setState({defaultBackHandler: true});
+ return true;
+ }
+
+ return false;
+ },
+
+ render: function() {
+ return (
+
+ {this.state.defaultBackHandler ? 'Ok, I\'ll quit.' : 'I won\'t quit.'}
+
+ );
+ },
+});
+
+exports.title = 'BackAndroid';
+exports.description = 'Custom back button handler';
+exports.examples = [
+ {
+ title: 'Custom back button handler',
+ render(): ReactElement { return ; }
+ }
+];
diff --git a/Examples/UIExplorer/UIExplorerList.android.js b/Examples/UIExplorer/UIExplorerList.android.js
index bb5b13a81..c8c8408c7 100644
--- a/Examples/UIExplorer/UIExplorerList.android.js
+++ b/Examples/UIExplorer/UIExplorerList.android.js
@@ -102,6 +102,10 @@ const APIExamples = [
key: 'AppStateExample',
module: require('./AppStateExample'),
},
+ {
+ key: 'BackAndroidExample',
+ module: require('./BackAndroidExample'),
+ },
{
key: 'BorderExample',
module: require('./BorderExample'),
diff --git a/Libraries/Utilities/BackAndroid.android.js b/Libraries/Utilities/BackAndroid.android.js
index 795380448..b8c997869 100644
--- a/Libraries/Utilities/BackAndroid.android.js
+++ b/Libraries/Utilities/BackAndroid.android.js
@@ -20,17 +20,19 @@ type BackPressEventName = $Enum<{
backPress: string;
}>;
-var _backPressSubscriptions = new Set();
+var _backPressSubscriptions = [];
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() {
- var backPressSubscriptions = new Set(_backPressSubscriptions);
- var invokeDefault = true;
- backPressSubscriptions.forEach((subscription) => {
+ var propagate = true;
+ for (var i = _backPressSubscriptions.length - 1; i >= 0; i--) {
+ var subscription = _backPressSubscriptions[i];
if (subscription()) {
- invokeDefault = false;
+ propagate = false;
+ break;
}
- });
- if (invokeDefault) {
+ }
+
+ if (propagate) {
BackAndroid.exitApp();
}
});
@@ -60,18 +62,18 @@ var BackAndroid = {
addEventListener: function (
eventName: BackPressEventName,
handler: Function
- ): {remove: () => void} {
- _backPressSubscriptions.add(handler);
- return {
- remove: () => BackAndroid.removeEventListener(eventName, handler),
- };
+ ): void {
+ _backPressSubscriptions.push(handler);
},
removeEventListener: function(
eventName: BackPressEventName,
handler: Function
): void {
- _backPressSubscriptions.delete(handler);
+ var index = _backPressSubscriptions.indexOf(handler);
+ if (index !== -1) {
+ _backPressSubscriptions.splice(index, 1);
+ }
},
};