React Native的项目中分为Android与IOS,但是若在现有的Android项目中,集成RN,不能按照那个包结构来,我们统一在app文件夹下处理。
一、集成步骤:
1.添加js文件
(1)在app文件夹下输入命令 npm init,生成package.json文件。这里会让你输入name等信息,除了name,其他可不输入。打开package.json文件,在scripts节点下,添加如下代码,注意逗号隔开"test"节点。
"start": "node node_modules/react-native/local-cli/cli.js start"
完整的package.json,我也贴出来:
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.2.0",
"react-native": "^0.52.1"
}
}
(2)安装React 和React Native:app下继续命令
npm install --save react react-native
这里需要一段时间,完成后,会在app目录下生成一个node_modules文件夹。
(3)配置其他文件。
a:将RN HelloWorld项目中的.flowconfig文件和.watchmanconfig文件拷贝过来;
b:将RN HelloWorld项目中的index.js和App.js文件拷贝过来,并将index.js文件中注册组件的名字与package.json中的名字一致(我使用的RN版本中已没有index.android.js文件了)。
AppRegistry.registerComponent('app', () => App);
2.项目配置
(1)配置app下的build.gradle文件。
a:添加RN库。
b:处理RN引用的so文件:RN中提供的libreactnativejni.so文件是32位,而Android项目中用了一些64位的so文件,导致不兼容。解决办法就是禁止使用那些64位的so文件。
c:appcompat-v7版本为23.0.1(只能使用该版本下的v7/v4包)。
贴下整个的配置:
android{
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
packagingOptions {
exclude "lib/arm64-v8a"
}
dependencies {
compile "com.facebook.react:react-native:+" // From node_modules.
compile 'com.android.support:appcompat-v7:23.0.1'
}
(2)项目的build.gradle中添加依赖
allprojects {
repositories {
google()
jcenter()
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/app/node_modules/react-native/android"
}
}
}
3.创建Activity
(1)创建MyRNActivity,继承ReactActivity,重写getMainComponentName()方法,返回值为package.json中的name值。
(2)创建MyApplication,继承Application,实现ReactApplication接口。
public class MyApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
(3)清单文件注册Activity和Application,并添加网络权限和DevSettingsActivity。至此,集成结束。贴下集成的目录:
二、运行
先在app目录下,启动node.js。再运行Android项目就可以了。
npm start
三、异常
(1)v4/v7包版本不对,只能使用23.0.1版本构建。如果你用的是自己已发布的项目,要注意引用库中v4/v7包的版本,必要的时候,将引用库中的v4/v7包排除掉。
IllegalAccessError: Method 'void android.support.v4.net.ConnectivityManagerCompat.<init>()
(2)so文件不统一。可以排除掉64位的so文件,具体配置见第二节。
java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so
(3)缺失 index.android.bundle文件。
Got JS Exception: ReferenceError: Can't find variable: __fbBatchedBridge
--> Unable to load script from assets: index.android.bundle
解决办法:
手动添加assets目录,创建index.android.bundle文件,使用命令打包js到该文件中。
react-native bundle --entry-file index.js --bundle-output ./src/main/assets/index.android.bundle --platform android --assets-dest ./src/main/res/ --dev false
(4) ReactNativeJS报错
ReactNativeJS: undefined is not a function (evaluating '(d.remoteModuleConfig||[]).forEach(function(e,n){var t=u(e,n);t&&(t.module?v[t.name]=t.module:h(v,t.name,{get:function(){return l(t.name,n)}}))})')
原因:项目下的build.gradle文件,引用node_modules路径错误,正确的如下:
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/app/node_modules/react-native/android"
}
(5)Cannot find entry file index.android.js in any of the roots。找不到index.android.js文件。查看官网的issue,找到了解决方案:复制index.js文件,命名为index.android.js即可。 链接地址:https://github.com/facebook/react-native/issues/18217