深入学习React Native之环境搭建

  移动端的开发在以前一般都是通过原生语言,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,和每个原生平台相关的代码;红色部分是每个系统平台的东西。

软件环境的安装配置

  需要的软件

  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的路径是如下格式:

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

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

ANDROID_HOME环境变量

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

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

1
2
3
4
%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\emulator
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin

adb连接设备

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

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

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

1
2
3
$ 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

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

1
2
3
4
5
$ 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]方式来执行:

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

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

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

adb shell

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

1
2
$ adb shell
shell@PD1415BA:/ $

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

1
2
3
4
5
6
7
8
9
10
11
12
# 查看所有安装的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

1
2
3
4
5
6
# 安装时指定apk的路径
$ adb install d:\chrome.apk

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

adb pull/push

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

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

无线连接

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

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

1
2
$ adb tcpip 1314
restarting in TCP mode port: 1314

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

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

1
2
$ adb connect 192.168.0.180:1314
connected to 192.168.0.180:1314

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

1
2
3
$ adb devices
List of devices attached
192.168.0.120:1314 device

IOS环境配置

  IOS下的环境配置相较于安卓则要容易些,不需要配置那么多繁琐的环境变量,只要把Xcode的IDE和Xcode的命令行工具,可以从APP开发者官网上下载;然后我们还要装一些其他的软件:

1
2
brew install node
brew install watchman

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  Watchman是 facebook 的一个开源项目,它开源用来监视文件并且记录文件的改动情况,当文件变更它可以触发一些操作,例如执行一些命令等等。

  然后我们可以使用yarn来代替npm管理我们的依赖包,方便加速下载。

1
npm install -g yarn

  启动Xcode,在Xcode -> Preferences -> Locations菜单中检查是否配置某个版本的Command Line Tools

  
Command Line Tools

  安装IOS模拟器只需要在Xcode -> Preferences -> Components下,就可以看到不同版本的模拟器,下载启动即可。启动模拟器的时候可能会遇到下面的报错:

1
2
fatal error: 'React/RCTBridgeDelegate.h' file not found 
#import <React/RCTBridgeDelegate.h>

  原因是一些依赖没有安装,切换到ios的目录下进行安装:

1
2
cd /ios
pod install

创建和运行RN项目

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

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

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

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

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

1
npm run android

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

第一个RN应用

  在Mac中则运行npm run ios命令,启动ios的模拟器:

IOS上RN应用

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

1
2
3
4
5
6
7
8
9
10
11
# 启动本地开发服务器
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只是启动开发服务器,并不安装应用程序,如果你的开发设备中已经有开发包,只需要启动服务器即可。

调试

  RN的开发,不仅涉及React中js的调试,还会涉及到样式、原生组件功能的调试,因此,掌握调试方式对我们的后续的开发有很大的帮助。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  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:开启调试

  当我们修改RN的代码后,肯定想第一时间就能看到修改后的效果,在原生App的开发中,修改后经常需要重新编译、运行等才可以看到效果;但是RN中我们可以直接通过开发者菜单上的Reload按钮自动完成代码的打包编译和运行,方便我们修改后直接查看效果。

  但是RN觉得这样还是要去点击Reload按钮,还不够,有没有什么更加“偷懒”的方式能够自动帮我们触发Reload呢?这就是快速刷新(Fast Refresh)功能,RN在监测到JS代码更改后,自动编译运行,立即就能看更改后的效果;如果觉得太频繁了,可以Disable禁用该功能。

  当我们只启动开发服务器,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文件。并在上面进行断点调试。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

断点调试

项目结构

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

1
2
3
4
5
6
7
8
9
10
11
12
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两个单独的入口文件。


本网所有内容文字和图片,版权均属谢小飞所有,任何媒体、网站或个人未经本网协议授权不得转载、链接、转贴或以其他方式复制发布/发表。如需转载请关注公众号【前端壹读】后回复【转载】。