</p>

说明: 本文仅适用于河狸家Android App的集成过程, 部分细节可能会和您的项目有出入. 您本地的新的安装包一般来说会比0.41.0新. 因为React Native更新很快, 建议开发中绑定一个版本.
  1. 首先一定要按照官方向导创建一个HelloWorld并运行成功, 建议做, 确保环境没问题  https://facebook.github.io/react-native/docs/getting-started.html
  2. 参考官方文档: https://facebook.github.io/react-native/docs/integration-with-existing-apps.html
  3. app的dependencies中一定要按照粗体这样写(减少全局配置文件带来的可能干扰):

a. 要填写本地node_modules的url作为依赖
b. 要填写固定版本的RN依赖, 例如默认是+, 很容易自动取到低版本(com.facebook.react:react-native:0.41.0), 会导致一些不必要的异常. </div>


</p>
先讲一个官方文档中的大坑:
In your project’s build.gradle file add an entry for the local React Native maven directory:
allprojects {
    repositories {
        …
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url “$rootDir/../node_modules/react-native/android”
        }
    }
    …
}

实践证明这样并不能成功找到对应版本的RN库(也许是因为各种build.gradle中的路径产生了冲突), 结果证实只能加到单个项目的build.gradle的dependencies这块一般是不会出问题的.

</font></div>


</p>
compileSdkVersion 23 // 22不行, 会报manifest等错误

</b></font>dependencies {
    compile fileTree(include: ‘*.jar’, dir: ‘libs’)
    repositories {
        mavenCentral()
        jcenter()
        maven { url https://jitpack.io}
        flatDir { dirs ‘libs’ }
        maven {  // All of React Native (JS, Android binaries) is installed from npm
            url “$rootDir/node_modules/react-native/android”
        }

    }
    compile “com.facebook.react:react-native:0.41.0” // From node_modules.</div>

检测标准:
</p>
protected void onPause() {
    super.onPause();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onHostPause(this);
    }
}

</font></div> </div>

上面的代码不会编译报错.
  1. 项目一般的本地第三方Lib有x86, armeabi等目录, 但是RN默认的lib库只有x86和armeabi-v7a, 所以要用到第一步中的APK所生成的so文件, 或者从本地的AAR解压缩: node_modules/react-native/android/com/facebook/react/react-native/0.41.0/react-native-0.41.0.aar, 将armeabi-v7a中的so库复制到armeabi中, 然后删除ndk中对armeabi-v7a的打包支持
android {

    compileSdkVersion
23
    buildToolsVersion '25.0.2'

    defaultConfig {
...

        /**
         * not like proguard, multiDexKeepProguard is not a list, so we can't just
         * add for you in our task. you can copy tinker keep rules at
         * build/intermediates/tinker_intermediates/tinker_multidexkeep.pro
         */
        multiDexKeepProguard file("keep_in_main_dex.txt")
        ndk {
           
//jpush 选择要添加的对应cpu类型的.so库。  还可以添加 'x86', 'x86_64', 'mips64','armeabi-v7a', 'armeabi-v8a',
            abiFilters 'armeabi', 'x86', 'mips'
        }

</div>

  1. 常见运行错误与解决

1). com.facebook.react.devsupport.JSException: Could not get BatchedBridge, make sure your bundle is packaged correctly

这个是因为没有打包jsbundle到app中. 解决方案需要新建assets目录(如果没有), 然后把JS打包进去, 用于发版时用.
react-native bundle –platform android –entry-file index.android.js –bundle-output android/app/src/main/assets/index.android.bundle –dev false
2). TypeError: undefined is not a function (evaluating ‘remoteModules.forEach’)
原因: node_modules 中的文件不完整, 解决方案: 从运行正常的项目出复制一份 或 重新初始化(注意保持网络环境良好), 参考: <a href="http://stackoverflow.com/questions/39924469/typeerror-undefined-is-not-a-function-evaluating-remotemodules-foreach"><font style="font-size: 13px;">http://stackoverflow.com/questions/39924469/typeerror-undefined-is-not-a-function-evaluating-remotemodules-foreach</font></a>
3). Could not connect to development server.
                                                           Try the following to fix the issue:
                                                           • Ensure that the packager server is running
                                                           • Ensure that your device/emulator is connected to your machine and has USB debugging enabled – run ‘adb devices’ to see a list of connected devices
                                                           • Ensure Airplane Mode is disabled
                                                           • If you’re on a physical device connected to the same machine, run ‘adb reverse tcp:8081 tcp:8081’ to forward requests from your device
                                                           • If your device is on the same Wi-Fi network, set ‘Debug server host & port for device’ in ‘Dev settings’ to your machine’s IP address and the port of the local dev server – e.g. 10.0.1.1:8081
                                                           URL: http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false
最快解决方案: adb reverse tcp:8081 tcp:8081
稍慢的方案或者要连别人的电脑调试: 摇晃设备, 打开 Dev Settings, 然后再点 Debugging 下面的
Debug server host & port for device, 输入开发机的局域网IP+端口8080, 例如: 10.0.1.1:8081
4). 如何启用实时刷新代码预览?
    摇晃设备, 打开 Dev Settings, 然后点击 Enable Hot Reload. 然后首次加载会稍微有点慢, 后面就可以实时预览了.
5): 什么是jest?
http://facebook.github.io/jest/ 一套号称0配置的JS测试框架
6): 错误 Seems you’re trying to access ‘ReactNative.createClass’ from the ‘react-native’ package. Perhaps you meant to access ‘React.createClass’ from the ‘react’ package instead?
                                                                   For example, instead of:
                                                                     import React, { Component, View } from ‘react-native’;
                                                                   You should now do:
                                                                     import React, { Component } from ‘react’;
                                                                     import { View } from ‘react-native’;
                                                                   Check the release notes on how to upgrade your code – https://github.com/facebook/react-native/releases/tag/v0.25.1
原因: 用了旧的Reac Native语法, 需要改写:
‘use strict’;

var React = require('react-native');
var {
    AppRegistry,
    StyleSheet,
    Text,
    View,
} = React;

var DoubanMovie = React.createClass({
    render: function() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    嗨,我是 Douban 1.0 版本 !
                </Text>
            </View>
        );
    }
});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    }
});

AppRegistry.registerComponent('DoubanMovie', () => DoubanMovie);
改为: 
import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    Button
} from 'react-native';


export default class DoubanMovie extends Component {
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    嗨,我是 Douban 1.0 版本 !
                </Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#FFFFFF',
        flexDirection: 'column'
    },

    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
        backgroundColor: '#008800',
    }
});

AppRegistry.registerComponent('DoubanMovie', () => DoubanMovie);

</div>

7): Hot loading isn’t working because it cannot connect to the development server.
                                                                   Try the following to fix the issue:
                                                                   – Ensure that the packager server is running and available on the same network
                                                                   – Ensure that your device/emulator is connected to your machine and has USB debugging enabled – run ‘adb devices’ to see a list of connected devices
                                                                   – If you’re on a physical device connected to the same machine, run ‘adb reverse tcp:8081 tcp:8081’ to forward requests from your device
                                                                   – If your device is on the same Wi-Fi network, set ‘Debug server host & port for device’ in ‘Dev settings’ to your machine’s IP address and the port of the local dev server – e.g. 10.0.1.1:8081
                                                                   URL: localhost:8081
                                                                   Error: Expected ‘Connection’ header value ‘Upgrade’ but was ‘null’
原因: 安卓机上跑了代理程序, 同时又运行了 adb reverse tcp:8081 tcp:8081 导致实际上Mac上的代理服务器不能很好的处理WebSocket请求.

</body></html>

转载请注明:WebLogic Android 博客 » React Native 集成到现有Android App中的常见错误及注意事项