1 hardwareBackPress
我们用hardwareBackPress来监听手机物理返回键
2 js那边常用写法
BackHandler.addEventListener('hardwareBackPress',this._back);
3 我们看下Android源代码分析是怎么触发到这里来的
1) ReactActivity.java里面的部分代码如下
@Override
public void onBackpressed() {
if (!mDelegate.onBackpressed()) {
super.onBackpressed();
}
}
2 ) 进入onBackpressed()函数看看,在ReactActivityDelegate.java文件里面
public boolean onBackpressed() {
if (getReactNativeHost().hasInstance()) {
getReactNativeHost().getReactInstanceManager().onBackpressed();
return true;
}
return false;
}
public void onBackpressed() {
UiThreadUtil.assertOnUiThread();
ReactContext reactContext = mCurrentReactContext;
if (reactContext == null) {
// Invoke without round trip to JS.
FLog.w(ReactConstants.TAG,"Instance detached from instance manager");
invokeDefaultOnBackpressed();
} else {
DeviceEventManagerModule deviceEventManagerModule =
reactContext.getNativeModule(DeviceEventManagerModule.class);
deviceEventManagerModule.emitHardwareBackpressed();
}
}
4) 进到emitHardwareBackpressed函数里面看下
/**
* Sends an event to the JS instance that the hardware back has been pressed.
*/
public void emitHardwareBackpressed() {
getReactApplicationContext()
.getJSModule(RCTdeviceeventemitter.class)
.emit("hardwareBackPress",null);
}
这里发现了Android原生向js发送了消息,所以我们监听hardwareBackPress就有反映
4 测试代码如下
App.js文件如下
import React from 'react';
import { View,Text,Button,NativeModules,BackHandler} from 'react-native';
import { createStackNavigator } from 'react-navigation';
var toast = NativeModules.MyToast;
class HomeScreen extends React.Component {
constructor(props) {
super(props);
console.log("HomeScreen constructor start");
}
static navigationoptions = {
title : 'HomeScreen',}
componentDidMount = () => {
this.didFocusListener = this.props.navigation.addListener(
'didFocus',(obj) => {
console.log("HomeScreen didFocus start");
BackHandler.addEventListener('hardwareBackPress',this._back);
}
);
this.didBlurListener = this.props.navigation.addListener(
'didBlur',(obj) => {console.log('HomeScreen didBlur start')}
);
console.log("HomeScreen componentDidMount start")
}
componentwillUnmount() {
console.log("HomeScreen componentwillUnmount start")
this.didFocusListener.remove();
this.didBlurListener.remove();
}
render() {
var testID = 'chenyu';
return (
<View style={{flex: 1,alignItems: 'center',justifyContent: 'center'}}>
<Text testID = {testID} onPress = {() => this._goto()}>Home Screen</Text>
<Button onPress={() => this.props.navigation.navigate('Details',{
itemId:100,otherParam:'chenyu',})} title = "go to Details"/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
_show(value) {
console.log(value);
}
_goto = () => {
toast.show();
}
_back = () => {
console.log("home back");
}
}
class DetailsScreen extends React.Component {
constructor(props) {
super(props);
console.log("DetailsScreen constructor start");
this.didFocusListener = this.props.navigation.addListener(
'didFocus',(obj) => {
console.log("DetailsScreen didFocus start");
BackHandler.addEventListener('hardwareBackPress',this._back);
}
);
this.didBlurListener = this.props.navigation.addListener(
'didBlur',(obj) => {console.log('DetailsScreen didBlur start')}
);
}
_back = () => {
console.log("detail back");
}
static navigationoptions = ({navigation}) => {
return {
title : navigation.getParam('otherParam','no-values'),};
};
componentDidMount = () => {
console.log("DetailsScreen componentDidMount start")
}
componentwillUnmount() {
console.log("DetailsScreen componentwillUnmount start")
this.didFocusListener.remove();
this.didBlurListener.remove();
}
render() {
const {navigation} = this.props;
const itemId = navigation.getParam('itemId','no-values');
const otherParam = navigation.getParam('otherParam','no-values');
return (
<View style={{ flex: 1,justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>itemId:{JSON.stringify(itemId)}</Text>
<Text>otherParam:{JSON.stringify(otherParam)}</Text>
<Button
title="Go to Details... again"
onPress={() => this.props.navigation.push('Details',{
itemId: Math.floor(Math.random() * 100),})}
/>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
<Button
title="Go popToTop"
onPress={() => this.props.navigation.popToTop()}
/>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: HomeScreen,Details: DetailsScreen,},{
initialRouteName: 'Home',}
);
export default class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return <RootStack/>;
}
}
5 运行结果
点击主界面的GO TO DETAILS,进入详细页面,然后分别按下2次back键,日志如下
10-27 23:39:32.498 917 1031 I ReactNativeJS: detail back
10-27 23:39:32.498 917 1031 I ReactNativeJS: home back
10-27 23:39:32.784 917 1031 I ReactNativeJS: DetailsScreen componentwillUnmount start
10-27 23:39:32.790 917 1031 I ReactNativeJS: HomeScreen didFocus start
10-27 23:39:51.164 917 1031 I ReactNativeJS: detail back
10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
10-27 23:39:51.165 917 1031 I ReactNativeJS: detail back
10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
10-27 23:39:51.165 917 1031 I ReactNativeJS: detail back
10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
10-27 23:39:51.165 917 1031 I ReactNativeJS: home back
10-27 23:39:51.165 917 1031 I ReactNativeJS: detail back
10-27 23:39:51.166 917 1031 I ReactNativeJS: detail back
10-27 23:39:51.166 917 1031 I ReactNativeJS: home back
10-27 23:39:51.166 917 1031 I ReactNativeJS: detail back
10-27 23:39:51.166 917 1031 I ReactNativeJS: home back
10-27 23:39:51.166 917 1031 I ReactNativeJS: home back
10-27 23:39:51.621 917 1031 I ReactNativeJS: HomeScreen componentwillUnmount start
我们点击标题栏的返回按钮,和点击GO BACK,执行this.props.navigation.goBack()方法,都不会触发hardwareBackPress监听所执行的函数
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。