官方文档:
https://reactnative.cn/docs/getting-started/
使用环境:
Windows & Android
缩略词:
RN(React Native)、AS(Android Studio)
1. 初始化项目
1.1 需要的环境
-
Node
Node 是 JS 的运行环境,这里注意需要下载的 Node 版本需要8.3以上。 -
Python 2
Python 2的运行环境,这里注意需要下载的python版本为 python 2.x ,不能是 python 3.x。 -
JDK
Java的运行环境,这里注意需要下载的JDK版本为1.8,只能是1.8。
1.2 需要的配置
由于国内把很多东西都墙掉了,国内的良心公司提供了不少代理,为我们的开发带来方便。下面的一些配置信息,由官网提供。
- npm 配置
npm 是 Node.js 的包管理工具,负责下载 js 代码的依赖包,由于被墙,我们需要配置下面的代理。
npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global
- yarn 配置(可选)
yarn 是用来替代 npm 功能的工具,可以加速 npm 的下载。
npm install -g yarn react-native-cli
安装完成后,依然需要未 yarn 设置代理。
yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global
2. 开始第一个项目
注意:在开始之前,请确定 1.1 和 1.2 的配置已经完成。
第一步
找到一个你认为合适的位置,执行如下命令,创建一个名为 Self 的 RN 项目:
react-native init Self
执行完成后,打开文件夹,可以看到如下内容:
第二步
连接我们的手机,打开开发者模式-允许usb调试,然后在项目文件夹下执行下面命令:
react-native run-android
执行完成后,会开始下载一些 Android 项目需要的依赖包,然后在手机上运行 App,效果如下:
注意:这里手机和电脑需要处于同一网段下,如果不在同一网段,可以左右剧烈摇晃手机,在弹窗中选择 Dev Settings - Debug server host & port for device 选项中输入 IP 和端口。
第三步
修改 App.js 文件,然后重启 App ,看是否能正常显示修改后的内容。
3. 集成 RN 项目到Android(Gradle项目)
3.1 准备工作
所谓准备工作,就是我们的 RN 项目。在集成进入 Android 中之前,我们需要确保我们的 RN 项目中存在 node_modules 这个文件夹。这个文件夹中存在 JavaScript 依赖的所有模块,一般情况下,从 GitHub 上 clone 的项目不会有这个文件夹的。
如果没有这个文件夹,我们需要在项目目录下,执行下面的命令:
npm install
如果使用的 yarn ,还可以直接执行:
yarn
生成的 node_modules 中有很多的文件夹,如果只有一个.开头的文件夹,说明是错误的。
然后,需要将 RN 服务器打开,在项目路径下执行下面命令:
react-native start
成功后会弹出一个新的窗口,用来打印 RN 服务器日志。
3.2 添加依赖
** 第一步 **
在 App项目 的 build.gradle 文件中添加如下代码:
allprojects {
repositories {
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
...
}
...
}
url "$rootDir/../node_modules/react-native/android" 这段代码实际上对应的是 node_modules/react-native/android 这个文件夹的真正地址,而 $rootDir 指的是项目根目录,如果你的 RN 项目和 App 不在同一目录下,那么这里应该是实际地址。Windows 下面的 '\' 符号需要换成 '\\' 符号。
第二步
在 App项目 的 build.gradle 文件中添加如下代码:
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
...
compile "com.facebook.react:react-native:+" // From node_modules
}
要指定特定的 React Native 版本,可以用具体的版本号替换 “+”,当然前提是你从 npm 里下载的是这个版本。
第三步
在==AndroidManifest.xml==下加上两个权限:
<uses-permission android:name="android.permission.INTERNET" />
3.3 编码及测试
由于主要测试集成结果,所以采用的简单的Demo,提供免费的下载链接:
CSDN(系统强制要的1分):RN项目集成测试
百度云盘(密码 mh4x):RN项目集成测试
在运行 Demo 前,请知晓如下几点:
- Demo 项目需要执行 npm install
- Demo 项目下开启 RN 服务器(具体方法参考3.1)
- 使用 AS 编译Demo_app
- 需要修改 Demo_app 项目下的 build.gradle (具体修改方法参考3.2)
- 运行 App 。如果是在真机上测试,手机和电脑需要在同一网段。
运行 App 时,分别输入 Demo 和 Demo2,会分别显示 App.js 和 APP.js 下面的内容,且修改两个文件后,刷新界面,可以正常显示。此时验证集成完毕。
4. 错误记录
4.1 Failed to resolve : com.facebook.react:react-native:xxx
这个问题发生在为 Android 项目添加了关于 React Native 的依赖时,出现问题的原因是因为无法下载相应的依赖,需要在 Android 项目的 build.gradle (不是 app 中的 build.gradle)文件中添加如下代码:
allprojects {
repositories {
...
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
...
}
特别注意:url "$rootDir/../node_modules/react-native/android" 这段代码实际上对应的是node_modules/react-native/android 这个文件夹的真正地址,而 $rootDir 指的是项目根目录,如果你的 RN 项目和 App 不在同一目录下,那么这里应该是实际地址。比如 Windows 下的路径:
maven{
url "F:\\Self\\node_modules\\react-native\\android"
}
4.2 Received malformed response from registry for undefined. The registry may be down.
这个问题发生在初始化项目时(react-native init xxx),原因是没有配置代理,依次执行下面的代码可正常初始化
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist
react-native init xxx
4.3 Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller than version 16 declared in library [com.facebook.react:react-native:0.55.4]
这个问题发生在将 RN 项目集成到其他项目中时(修改完 build.gradle 之后),出现这个问题的原因,是因为我们的 RN 要求的最低 SDK 版本是 16 ,而我们项目中实际的最低版本小于16。解决办法,就是修改 app 的最低 SDK 版本。
4.4 Unexpected end of JSON input while parsing near '..."_hasShrinkwrap":fals'
这个问题发生在使用 github 上面其它人的项目后,在生成 node_modules 文件夹时(执行 npm install 或者 npm update 命令时报错)。百度候找到的解决方案大部分都是下面这个方法:
npm cache clean --force
上面的这个方法清除了 npm 的缓存,但是实际验证还是会有问题。后面找到了网上其它的说法,指出可能是 npm 和 node 的版本不合适导致的,参考:Unexpected end of JSON input while parsing near错误解决方式(网上的方法)
后面依次执行了下面的命令,最终成功生成了该文件夹:
npm -g i npm@4
npm cache clean --force
npm install
重点来了
上面的这个过程很麻烦,并且降低了 npm 的版本后会不会导致其它环节出问题,谁也不知道。这属于不确定因素。所以这里还提供一个简单的办法:
安装 yarn:
npm install -g yarn react-native-cli
配置代理:
npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global
yarn 是 Facebook 提供的用来替换 npm 的工具,执行如下命令后就可以替代 npm install :
4.5 java.lang.UnsatisfiedLinkError: could find DSO to load:libreactnativejni.so
同类问题包括:
java.lang.UnsatisfiedLinkError: dlopen failed: "xxx/libgnustl_shared.so" is 32-bit instead of 64-bit
产生这个问题的原因,是因为 RN 中同时存在 arm64-v8a 和 armeabi-v7a 的 so 文件,在打包时,只会将 arm64-v8a 的 so 打入 app ,导致找不到 armeabi-v7a 对应的 so 文件。具体的原因和分析可以看:【ReactNative】关于32位和64位SO库混合引入Crash解决方案
解决方法,在 app 的 build.gradle 中加入下面配置:
defaultConfig {
...
ndk{
abiFilters "armeabi-v7a","x86"
}
packagingOptions {
exclude "lib/arm64-v8a/libimagepipeline.so"
}
}
4.6 Program type already present: android.support.v4.app.ActionBarDrawerToggle$DelegateProvider
同类问题包括:
Program type already present: xxx
这个问题出现在编译 App 包时,是由于RN 中依赖的包和其它依赖包有重复,需要 exclude 其中的一个包:
implementation("com.facebook.react:react-native:0.55.4"){ // From node_modules
exclude module: 'android.support.v4'
}
4.7 Failed to resolve: com.facebook.react:react-native:0.55.5
同类问题包括:
Failed to resolve: com.facebook.react:react-native:xxx
这个问题出现在 Build 阶段,是由于无法下载 RN 的依赖导致,具体的原因是由于手动将 com.facebook.react:react-native:+ 修改成了其它版本。
我们查看官方文档可以发现,添加 RN 的依赖时,我们可以看到一段注释: // From node_modules 。这段注释告诉我们,我们依赖进入项目的 RN 版本是有 node_modules 决定的。也就是 RN 项目下的 package.json 内部定义的。
所以,我们解决这个问题的办法有三个:
- 直接使用 com.facebook.react:react-native:+
- 根据 package.json 内部定义,修改依赖的版本
- 修改 package.json 内部定义
上面的三个方案,有两点需要注意:
- 直接使用 com.facebook.react:react-native:+ 时,依然可能出现导入的 react-native 包的版本与 package.json 中的定义不一样,这时候,我们先在 App 中去掉这个依赖,然后 clear 工程,在 RN 目录下,删除 node_modules 文件夹,再通过命令重新生成,之后再在 App 中加入依赖。
- 修改 package.json 内部定义后,也需要重新生成 node_modules 文件夹
4.8 com.facebook.react.bridge.JSExecutionException: TypeError: undefined is not a function (evaluating '(bridgeConfig.remoteModuleConfig||[]).forEach')
这个问题可能会出现在 App 访问 RN 的 Activity 时出现,目前具体原因还不清楚,只能基本确定和我们的依赖有关。
解决方案(仅供参考):
这个问题会伴随着一个 url 链接,我们首先通过浏览器访问这个 url ,首先确定我们的 RN 服务器是正常的,其正常界面入下图所示:
如果没出现上图界面
说明我们的 RN 代码有问题,先检查 RN 服务器是否打开,如果不行就删除 node_models 重建。
如果出现上图界面
说明 App 的依赖存在问题,参考 4.7 的三个办法中的第一个办法以及对应的注意点进行操作。
5. Demo 地址
6. 鸣谢
Unexpected end of JSON input while parsing near错误解决方式(网上的方法)