移动端的开发在以前一般都是通过原生语言,Android通过JAVA,IOS通过Object-C或者Swift;对于开发同一个APP通常要两个团队来维护两套代码,对于小公司而言还是比较有成本的。因此越来越多的公司选择React Native来开发App,这样就做到了一个团队维护一套代码,无疑是节省了很大的人力成本。
本文首发于公众号
【前端壹读】
,更多精彩内容敬请关注公众号最新消息。
RN简介
React Native(简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,用于创建本地移动Android
和iOS
平台应用程序。它基于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 Virtual Device
:
Android Studio默认会安装最新版本的Android SDK,我们可以查看它的配置路径,具体路径是Appearance & Behavior → System Settings → Android SDK
;默认SDK的路径是如下格式:
C:\Users\你的用户名\AppData\Local\Android\Sdk
复制代码
RN需要环境变量来知道我们的SDK安装在什么路径下,从而来编译;打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设置 -> 高级 -> 环境变量 -> 新建
,创建一个ANDROID_HOME
的环境变量,指向我们上面找到的SDK所在的目录。
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应用了:
我们来看下package.json
中有哪些启动命令:
# 启动本地开发服务器
npm run start
# 将APP运行在iOS设备上,仅仅Mac系统支持,且需要安装Xcode。
npm run ios
# 将APP运行在Android设备上,需要Android构建工具。
npm run android
# 运行测试用例。
npm test
复制代码
很多童鞋看到这几个命令很疑惑,npm run start
和npm 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.js
和index.android.js
两个单独的入口文件。
更多前端资料请关注公众号``【前端壹读】``。
复制代码