在react原生Android上远程调试JS会挂起设备



我将2013 Nexus 4升级到了Android 5.1,并使用它开发了一个具有https://github.com/ideacreation/react-native-barcodescanner,并使用"导航器"组件进行导航。

这是我的反应版本

"react": "15.0.2",
"react-native": "0.26.1",
"react-native-barcodescanner": "2.0.0"

在最初部署了react native run android之后,我通常会在开发过程中运行:

adb  -d reverse tcp:8081 tcp:8081
react-native start
adb logcat *:S ReactNative:V ReactNativeJS:V

每次更新我的index.android.JS(我正在更改的唯一文件)时,我都会愤怒地摇手机重新加载JS。然而,当我选择远程调试JS时,我的设备会陷入停顿/挂起。简单的屏幕导航变得不可能,15秒以上,可能会挂起。我以前只在欢迎屏幕react原生示例上试用过DebugJS Remotely,效果很好。

问题:当我尝试远程调试JS时,设备变得如此无响应的原因是什么?有什么解决办法吗?

=====

在下面附上我的index.android.js,以表明我没有做任何花哨的事情:

/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TouchableHighlight,
View,
Image,
ListView,
Navigator,
BackAndroid
} from 'react-native';
import BarcodeScanner from 'react-native-barcodescanner';
import _ from 'underscore';
// get this baseUrl after you run "ngrok http <port>" or point to heroku
var baseUrl = "http://awesome-footprints.herokuapp.com/";
class HomeToolbar extends Component {
render() {
//debugger
return (<View>
<View style={styles.toolbar}>
<TouchableHighlight style={styles.toolbarButton} underlayColor="grey" onPress={this.props.onPress}>
<Text style={styles.toolbarButtonText}>Scan</Text>
</TouchableHighlight>
<Text style={styles.toolbarTitleOneButton}>
Awesome Footprints
</Text>
</View>
<View>
<Text style={styles.instructions}>
{"n"} Step 1: Press the Scan button
</Text>
<Text style={styles.instructions}>
{"n"} Step 2: Scan your product's barcode
</Text>
<Text style={styles.instructions}>
{"n"} Step 3: View the environmental impacts.  Simple!
</Text>
<Image
style={styles.logo}
source={require('./awesome_footprint_400_400.png')}
/>
</View>
</View>)
}
}
class Home extends Component {
_navigate() {
this.props.navigator.push({
name: "Scanner",
component: Scanner
});
}
render() {
return <HomeToolbar onPress={this._navigate.bind(this)}/>
}
}
class ScanToolbar extends Component {
render() {
return (<View>
<View style={styles.toolbar}>
{/*<TouchableHighlight style={styles.toolbarButton} underlayColor="grey" onPress={this.props.navigator.pop}>*/}
<TouchableHighlight style={styles.toolbarButton} underlayColor="grey" onPress={this.props.onPress}>
<Text style={styles.toolbarButtonText}>Back</Text>
</TouchableHighlight>
<Text style={styles.toolbarTitleOneButton}>
Awesome Footprints
</Text>
</View>
</View>)
}
}
class Scanner extends Component {
constructor(props) {
super(props);
this.state = {
torchMode: 'off',
cameraType: 'back',
barCode: '',
barCodeType: '',
tested: false,
testOnPress: this._test.bind(this),
onBarCodeRead: this.barcodeReceived.bind(this)
};
}
_navigateResult(){
this.props.navigator.push({
title: 'DisplayImpacts',
component: DisplayImpacts,
barCodeType: this.state.barCodeType,
barCode: this.state.barCode,
popCallback: this._popCallback.bind(this),
});
}
barcodeReceived(e) {
// debugger
console.log('Barcode: ' + e.data);
console.log('type: ' + e.type);
this.setState( {barCode: e.data, barCodeType: e.type, onBarCodeRead: null}, () => this._navigateResult());
}
_navigateBack() {
this.props.navigator.pop();
}

_popCallback() {
this.setState( {onBarCodeRead: this.barcodeReceived.bind(this)} );
}
_test() {
console.log("test");
this.setState({tested: true, testOnPress: null});
}
render() {
var text = this.state.tested ? 'Tested' : 'Untested';
return (
<View style={styles.containerScan}>
<ScanToolbar onPress={this._navigateBack.bind(this)}/>
<BarcodeScanner
onBarCodeRead={this.state.onBarCodeRead}
style={{flex: 1}}
torchMode={this.state.torchMode}
cameraType={this.state.cameraType}
/>
</View>
);
}
}
class DisplayImpacts extends Component {
constructor(props) {
super(props);
this.state = {
resJson: {},
};
this.storeImpactJson = this.storeImpactJson.bind(this);
}
componentDidMount(){
this.getImpacts();
}
_navigateBack() {
this.props.route.popCallback();
this.props.navigator.pop();
}
storeImpactJson(resJson) {
this.setState({resJson: resJson});
}
getImpacts() {
fetch(baseUrl + "/products/lookup.json?barcode_type=" + this.props.route.barCodeType + "&barcode=" + this.props.route.barCode )
.then(function(res) {
return res.json();
})
.then(this.storeImpactJson)
}
render() {
var impactsView;
if (_.isEmpty(this.state.resJson))
{
impactsView = <Text>Initializing...</Text>
}
else {
impactsView = <ImpactsView resJson={this.state.resJson}></ImpactsView>
}
return (<View>
<ScanToolbar onPress={this._navigateBack.bind(this)}/>
<Text style={styles.impactDisplayTitle}>Total Impacts</Text>
{impactsView}
</View>)
}
}
class ImpactRowView extends Component {
constructor(props) {
super(props);
}
render() {
var heading = Object.keys(this.props.data)[0];
var value = this.props.data[heading];
return (
<View style={styles.impactRowContainer}>
<Text style={styles.impactRowHeading}>{heading}</Text>
<Text style={styles.impactRowValue}>{value}</Text>
</View>
)
}
}
class ImpactsView extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => _.isEqual(r1, r2)});
this.state = {
dataSource: ds.cloneWithRows([]),
};
}
render() {
var product = this.props.resJson["product_lookup"]
var id = product["id"];
var name = product["name"];
var barcodeType = product["barcodeType"];
var barcode = product["barcode"];
var totalImpact = product["total_impact"];
impactsDataSource = [];
for (var key in totalImpact) { impactsDataSource.unshift({[key]: totalImpact[key]}); }
console.log(JSON.stringify(impactsDataSource));
return (
<View>
<View>
<Text style={styles.productInfo}>Product Id: {id}</Text>
<Text style={styles.productInfo}>Name: {name}</Text>
<Text style={styles.productInfo}>Barcode Type: {barcodeType}</Text>
<Text style={styles.productInfo}>Barcode: {barcode}</Text>
</View>
<ListView
dataSource={this.state.dataSource.cloneWithRows(impactsDataSource)}
renderRow={(rowData) => <ImpactRowView data={rowData}/>}
/>
</View>
)
}
}
class AwesomeFootprints extends Component {
_renderScene (route, navigator) {
var Component = route.component;
return (
<Component {...route.props} navigator={navigator} route={route} />
);
}
render() {
return (
<Navigator
initialRoute={{
name: "Home",
component: Home
}}
configureScene={() => {
return Navigator.SceneConfigs.FloatFromRight;
}}
renderScene={this._renderScene} />
);
}
}

const styles = StyleSheet.create({
logo: {
flex: 1,
resizeMode: 'cover',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
containerScan: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
color: '#333333',
marginBottom: 5,
marginRight: 15,
marginLeft: 15,
fontSize: 16,
},
toolbar: {
backgroundColor:'#81c04d',
paddingTop:30,
paddingBottom:10,
flexDirection:'row'
},
toolbarButton:{
width: 100,
marginLeft: 20,
},
toolbarButtonText:{
color:'#fff',
fontSize: 20,
},
toolbarTitle:{
color:'#fff',
textAlign:'center',
fontWeight:'bold',
flex:1,
fontSize: 20,
},
toolbarTitleOneButton:{
color:'#fff',
justifyContent: 'flex-start',
fontWeight:'bold',
flex:1,
fontSize: 20,
},
productInfo:{
fontSize: 16,
marginLeft: 15,
marginBottom: 5,
},
impactDisplayTitle:{
textAlign: 'center',
fontSize: 24,
color: 'green',
marginTop: 10,
marginBottom: 10,
},
impactRowContainer:{
flexWrap: 'wrap',
alignItems: 'flex-start',
justifyContent: 'space-between',
flexDirection:'row',
borderWidth: 1,
borderColor: 'black',
marginLeft: 15,
marginRight: 15,
paddingBottom: 30,
},
impactRowHeading:{
fontSize: 20,
},
impactRowValue:{
fontSize: 20,
},
});
AppRegistry.registerComponent('AwesomeFootprints', () => AwesomeFootprints);

可能与此问题有关https://github.com/facebook/react-native/issues/7707

最新更新