在反应原生的Android上远程调试JS会挂起设备

时间:2016-06-08 17:02:43

标签: android react-native

我将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(只有我正在更改的文件)时,我会愤怒地将手机摇到Reload JS。但是,当我选择远程调试JS时,我的设备会停止/挂起。简单的屏幕导航变得不可能,15秒以上,并且可以挂起。我曾经尝试过远程调试JS,当时我只在欢迎屏幕上反应原生样本,并且工作正常。

问题:一旦我尝试远程调试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);

1 个答案:

答案 0 :(得分:0)