深入学习React Native之环境搭建

1,739 阅读10分钟

  移动端的开发在以前一般都是通过原生语言,Android通过JAVA,IOS通过Object-C或者Swift;对于开发同一个APP通常要两个团队来维护两套代码,对于小公司而言还是比较有成本的。因此越来越多的公司选择React Native来开发App,这样就做到了一个团队维护一套代码,无疑是节省了很大的人力成本。

本文首发于公众号【前端壹读】,更多精彩内容敬请关注公众号最新消息。

RN简介

  React Native(简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,用于创建跨平台移动AndroidiOS平台应用程序。它基于Facebook的JavaScript库React,为移动平台创建用户界面。

官方slogan:一次学习,随处编写

  开发人员可以使用React Native编写Android和iOS应用程序,这些程序的操作和外观都与原生应用程序相似。使用React Native编写的代码也可以跨平台共享,这就允许IOS和Android同时进行高效开发;React Native有以下优势:

  • 免费的,开源的,有大型的社区支持
  • 接近原生性能
  • 节省跨平台应用程序开发时间
  • 实时和热重载

  但是它同时也有不少缺点:

  • 兼容性和调试问题
  • 缺乏安全稳健性,React Native是一个JavaScript库和开源框架,它在安全性方面存在重大问题
  • React Native在最初渲染之前需要花费大量时间来初始化运行,因为JavaScript线程需要时间来初始化
  • 仍然需要Native开发人员

  那么React Native是如何做到跨平台的呢?我们先看下React和React Native的区别,很多童鞋对他们俩的关系都傻傻分不清:

  • React是一个基于JavaScript的应用程序开发框架。
  • React Native是一个允许用户开发跨平台和移动应用程序的平台

  首先我们需要知道的是:React只是一个纯JS库,它不涉及任何移动平台的功能,React的代码经过编译后需要JS Engine来进行解析执行;它封装了一套Virtual Dom的概念,实现驱动编程模式,为复杂的Web UI实现了一种无状态管理的机制;但是底层的一些事情,比如驱动原生控件展示、读写磁盘、网络等,它就无能为力了。

  但是React Native就不一样了,JSX的源码通过React Native编译后,通过对应平台的Bridge实现了与原生框架的通信;Bridge的作用就是给RN内嵌的JS提供原生接口的扩展供JS调用;所有的原生功能,例如原生控件绘制、图片资源、本地存储、网络访问、地图定位等功能,都是通过Bridge封装成JS接口注入JS Engine供JS调用。

  我们通过一张图来具体的看下:

技术架构

  绿色的部分就是我们应用开发的部分,主要就是我们写的JSX代码;蓝色部分代表公用的跨平台的代码和工具引擎;黄色的部分就是我们的Bridge,和每个原生平台相关的代码;红色部分是每个系统平台的东西。

软件环境的安装配置

  需要的软件

  • JDK == 1.8
  • Android Studio
  • Nodejs >= 12

  React Native要求JDK的版本为1.8,我们从官网下载适合自己系统的jdk,然后配置系统的环境变量,网上有很多教程,这里就不再赘述。

  然后配置Android环境,从官网下载Android Studio,下载下来是一个exe程序:

Android Studio安装

  在安装界面中我们可以勾选Android Virtual Device

勾选AVD

  Android Studio默认会安装最新版本的Android SDK,我们可以查看它的配置路径,具体路径是Appearance & Behavior → System Settings → Android SDK;默认SDK的路径是如下格式:

C:\Users\你的用户名\AppData\Local\Android\Sdk

  RN需要环境变量来知道我们的SDK安装在什么路径下,从而来编译;打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设置 -> 高级 -> 环境变量 -> 新建,创建一个ANDROID_HOME的环境变量,指向我们上面找到的SDK所在的目录。

ANDROID_HOME环境变量

  SDK下有一些工具,我们需要在全局使用,打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设置 -> 高级 -> 环境变量,选中Path变量,然后点击编辑,将以下目录添加进去:

%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\emulator
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin

adb连接设备

  Android Debug Bridge(安卓调试桥),是一个命令行窗口,用于通过电脑端与模拟器或者是安卓设备之间的交互;adb是一个标准的CS结构的工具,主要包含如下三部分:

  • Client端:运行在开发机器中, 即你的开发PC机. 用来发送adb命令.
  • Deamon守护进程:运行在调试设备中, 即的调试手机或模拟器.
  • Server端:作为一个后台进程运行在开发机器中, 即你的开发PC机. 用来管理PC中的Client端和手机的Deamon之间的通信.

  adb的下载和安装主要有两种方式,第一种直接下载adb的工具压缩包解压,然后将它的目录配置到环境变量Path中;第二种就是利用上面已经安装的Android Studio,它本身带有adb工具,在SDK目录下的platform-tools中;如果按照上一节配置好Android Studio的环境变量,一般是直接可以调用adb命令的。

  在命令行输入adb version查看版本号,如果有输出,就已经配置成功了。

$ adb version
Android Debug Bridge version 1.0.41
Version 31.0.3-7562133

  配置好环境后,我们还需要打开android手机的USB调试功能;首先要进入手机的开发者模式,在手机设置 -> 关于手机连续点击版本号七次就打开了开发者模式;然后进入设置 -> 开发者选项,打开USB调试以及允许ADB的一些权限,这样手机就配置好了。下面我们来看下adb的一些常用命令。

adb start/kill-server

  启动/杀死adb,我们在上面提到的Server端进程,由于adb并不稳定,有时候莫名的问题掉线时,可以先kill-server, 然后start-server来确保Server进程启动. 往往可以解决问题.

adb devices

  列举当前连接的调试设备:

$ adb devices
List of devices attached
cf264b8f	device
emulator-5554	device
10.129.164.6:5555	device

  其中前面的一串字符串代表了手机的serialNumber,后面的device代表手机的连接状态,有以下几种状态:

  • device:设备已连接
  • offline:表示设备未连接成功或无响应;
  • unauthorized:设备还没有授权,需要在设备上进行确认

  我们可以通过手机的serialNumber看出设备的类型,第一个字母和数字的代表usb连接的设备,emulator表示是一个Android模拟器,而最后一个IP端口的表示是通过无线网络的方式连接的。

  如果我们同时连接了多个设备,需要操作其中一台设备,可以通过-s [serialNumber]方式来执行:

$ adb -s 9d03b4c4 shell wm size
# Physical size: 1080x1920

  比如上面的指令,我们指定9d03b4c4这个设备来获取屏幕分辨率。

adb shell

  Android系统是基于Linux内核的,所以Linux里的很多命令在Android里也有相同或类似的实现,在adb shell里可以调用;进入设备的shell界面,此时可以使用很多指令:

$ adb shell
shell@PD1415BA:/ $ 

  此时如果想要退出可以输入exit,我们也可以通过adb shell [指令]的方式执行,不需要进入设备的shell界面。

# 查看所有安装的apk包名
adb shell pm list package
# 查看实时资源占用情况
adb shell top
# 截图保存到设备里
adb shell screencap -p /sdcard/sc.png
# 录制屏幕
adb shell screenrecord /sdcard/sr.mp4
# 模拟按键/输入
adb shell input keyevent <keycode>
# 滑动屏幕
adb shell input swipe 300 1000 300 500

adb install/uninstall

  安装和卸载apk

# 安装时指定apk的路径
$ adb install d:\chrome.apk

# 卸载apk时指定包名
# 包名是上面pm获取到的package
$ adb uninstall com.tencent.mobileqq

adb pull/push

  在调试设备和开发PC之间拷贝文件,从PC拷贝文件到设备中用push;用设备拷贝文件到PC中用pull

$ adb push d:\1.png /sdcard/
$ adb pull /sdcard/2.png d:\temp\

无线连接

  通过无线网络连接,我们就可以无需USB实际连接设备,也可以避免USB连接不稳定等问题出现。

  首先确保ADB的版本不宜过低(至少30.0.0),然后将Android设备和调试PC机连接到同一个局域网;首次连接我们还是需要将手机通过USB连接PC,然后开启调试的端口,端口号建议选用不常用未被占用的端口:

$ adb tcpip 1314
restarting in TCP mode port: 1314

  端口开启后,我们就可以移除USB的连接,然后查看手机WiFi的IP地址,然后通过adb去进行连接:

$ adb connect 192.168.0.180:1314
connected to 192.168.0.180:1314

  连接后我们可以通过devices来查看设备是否连接成功:

$ adb devices
List of devices attached
192.168.0.120:1314      device

创建和运行RN项目

  我们先安装React Native脚手架,然后通过脚手架来创建一个demo项目:

npm install -g react-native-cli
react-native init RNDemo

  接下来,我们就需要一台安卓设备了,既可以是真机,也可以是安卓模拟器;安卓官方提供了Android Virtual Device(简称 AVD)的模拟器,在Android Studio中,打开AVD Manager来创建和管理模拟器,不过官方的性能较差,我们可以安装一些第三方的。

  这里推荐夜神模拟器,安装后通过adb连接,我们可以在项目里运行以下命令进行编译和安装:

npm run android

  需要注意的是,第一次编译需要下载依赖,会比较慢;如果配置都没有问题,我们就可以在设备上看到我们第一个RN应用了:

第一个RN应用

  我们来看下package.json中有哪些启动命令:

# 启动本地开发服务器
npm run start

# 将APP运行在iOS设备上,仅仅Mac系统支持,且需要安装Xcode。
npm run ios

# 将APP运行在Android设备上,需要Android构建工具。
npm run android
    
# 运行测试用例。
npm test

  很多童鞋看到这几个命令很疑惑,npm run startnpm run android/ios不都是启动么?有什么区别?

  npm run android/ios在启动开发服务器的同时,会检测有没有设备已经连接;如果有的话,会将开发包安装到开发设备中(安卓or苹果手机),而npm run start只是启动开发服务器,并不安装应用程序,如果你的开发设备中已经有开发包,只需要启动服务器即可。

调试

  Developer Menu(简称DevMenu)是React Native给开发者定制的一个开发者菜单,来帮助开发者调试React Native应用;如果是在iOS模拟器中运行,可以通过按下Command⌘ + D 快捷键来打开:如果是在Android官网模拟器中,则是Command⌘ + M,在第三方模拟器中一般在侧边栏中有一个菜单键;在Android真机中可以通过摇晃设备来打开。

调试菜单

  我们看到菜单中有下面几个选项:

  • Reload:刷新页面
  • Change Bundle Location:改变打包后的地址
  • Show Element Inspect:显示元素检查
  • Disable Fast Refresh:禁止快速刷新
  • Show Perf Monitor:该功能启用后会显示一个监控窗口,显示出实时的内存占用、UI 和 JavaScript 的 FPS 等信息。帮助我们调试性能问题。
  • Settings:设置
  • Enable Sampling Profiler:启用采样分析器
  • Debug:开启调试

  当我们只启动开发服务器,adb也已经连接设备,但是在开发设备中出现No apps connected. Sending "reload" to all React Native apps failed的错误提示时,我们可以在开发者菜单中选择Change Bundle Location,然后输入``:8081```来连接我们的开发服务器。

  Show Element Inspect选项可以调出元素检查的悬浮框,展示当前选中元素的位置、样式、层级关系、盒子模型信息等等,有点类似Chrome的DevTools,让我们可以很方便的调试元素的样式。

元素检查

  Debug允许我们在Chrome中调试应用,其调试方式和我们在Web中调试一模一样;点击该选项,会自动启动Chrome浏览器,并且打开一个http://localhost:8081/debugger-ui/的新标签页,在这个标签页里,我们打开开发者工具,就能看到JS输出的日志信息了。

输出日志信息

  在Sources Tab页中还可以显示当前调试项目的所有js文件。并在上面进行断点调试。

断点调试

项目结构

  熟悉项目的结构,是项目上手的第一步,也是最重要的一步,有助于我们更好的理解项目,我们来看下项目中每个文件是做什么的:

RNDemo                              
  ├── /_test_                  # 测试目录
  ├── /android                 # Android的原生开发目录,可以用Android Studio打开进行原生开发。
  ├── /ios                     # Ios的原生开发目录,可以用Xcode打开进行原生开发。
  ├── .buckconfig              # buck的配置文件,buck是Facebook推出的一款高效率的App项目构建工具。
  ├── .eslintrc.js             # eslint配置文件
  ├── .flowconfig              # Flow的配置文件
  ├── .watchmanconfig          # 用于监控bug文件和文件变化,并且可以出发指定的操作。
  ├── App.js                   # 整个App的入口文件,比如整个项目的路由在这里导入
  ├── app.json                 # 给原生app打包用,包括项目名称和手机桌面展示名称
  ├── index.js                 # ios或android的入口
  ├── metro.config.js          # Metro配置文件

  index.js这个文件是IOS和Android在相应设备上打包运行的入口文件,在0.49之前版本的React Native项目,入口则是index.ios.jsindex.android.js两个单独的入口文件。

更多前端资料请关注公众号``【前端壹读】``

如果觉得写得还不错,请关注我的掘金主页。更多文章请访问谢小飞的博客