React Native移动开发实战 第3版

978-7-115-62607-3
作者: 向治洪
译者:
编辑: 韩松

图书目录:

详情

React Native 是一款当前市面上流行的前端跨平台开发框架。近年来,随着大规模重构和优化,React Native 在性能和兼容性方面得到了大幅度的提升。为帮助广大开发人员快速开展 React Native 应用开发,本书从 React Native 入门、React Native 开发进阶、热更新和应用打包等方面,以大量实例,系统地介绍了 React Native 知识点。本书还提供了一个影城应用项目以供读者学习、实战。书中每个阶段的知识都是层层深入且环环相扣的,能够帮助读者对 React Native 框架的原理与应用有一个全面的认识。 本书适合具有一定原生 Android、iOS 开发基础的一线应用开发工程师、大中专院校相关专业师生、培训班学员阅读,可以帮助读者夯实基础,提升 React Native 开发实战技能。

图书摘要

版权信息

书名:React Native移动开发实战第3版

ISBN:978-7-115-62607-3

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

版  权

编  著 向治洪

责任编辑 张天怡

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

内 容 提 要

React Native是一款当前市面上流行的前端跨平台开发框架。近年来,随着大规模重构和优化,React Native在性能和兼容性方面得到了大幅度的提升。为帮助广大开发人员快速开展React Native应用开发,本书从React Native入门、React Native开发进阶、热更新和应用打包等方面,以大量实例,系统地介绍了React Native知识点。本书还提供了一个影城应用项目以供读者学习、实战。书中每个阶段的知识都是层层深入且环环相扣的,能够帮助读者对React Native框架的原理与应用有一个全面的认识。

本书适合具有一定原生Android、iOS开发基础的一线应用开发工程师、大中专院校相关专业师生、培训班学员阅读,可以帮助读者夯实基础,提升React Native开发实战技能。

前  言

经过10多年的快速发展,移动互联网早已取代传统的PC互联网,成为互联网发展的主要方向。不过,随着移动技术发展得越来越成熟,越来越多的企业和开发者也开始关注如何更高效、更低成本地开发移动应用。

众所周知,传统的原生Android、iOS开发技术虽然比较成熟,但是多端重复开发的成本和开发效率的低下是很多企业不愿意看到的,而不断崛起的跨平台技术让企业看到了曙光,“一次编写,处处运行”也不再是难以企及的目标。

目前,市面上流行的跨平台技术主要分为三种:第一种是基于Web浏览器的Hybrid技术方案,采用此种方案时只需要使用HTML5及JavaScript进行开发,然后使用浏览器加载即可实现应用跨平台;第二种是通过在不同平台上运行某种语言的虚拟机来实现应用跨平台,采用此种方案的跨平台技术主要有React Native和Weex;第三种是使用自带渲染引擎实现的跨平台渲染方案,代表技术有QT Mobile和Flutter。

不过,不管是哪种技术,相比传统的移动原生开发技术来说,都是质的提升,它们不仅降低了开发的难度,还提升了开发的效率。事实上,作为目前流行的跨平台技术方案之一,React Native是Facebook(已于2021年10月更名为Meta)技术团队于2015年4月开源的一套跨平台开发框架,开发的应用可以同时运行在Android、iOS两大移动平台上。并且,经过8年多的发展,React Native不仅可以支持开发移动跨平台应用,还支持开发Web应用,是一款名副其实的前端跨平台开发框架。

为了最大限度地提升应用体验,React Native抛弃了传统的浏览器加载的思路,转而采用调用原生API的思路来实现界面的渲染,最终获得了媲美原生移动应用的使用体验。同时,React Native使用JavaScript作为开发语言,也降低了开发的成本,让更多的前端Web开发者加入跨平台开发的行列。

当然,React Native也并不是完美无缺,比如社区反映的比较明显的缺点有首次加载慢、调试不友好、需要定期升级等,不过这些问题相对于跨平台的先进性来说都是可以克服的。并且随着最近两年React Native开启大规模的重构和优化,React Native在性能和兼容性方面都得到了大幅度的提升。在最新的架构中,React Native使用Hermes替换了传统的JavaScriptCore渲染引擎,使得页面的渲染速度更是得到了质的改善。

“路漫漫其修远兮,吾将上下而求索”,通过React Native跨平台技术的学习和本书的写作,我深刻地意识到学无止境的含义。2015年4月,React Native发布了第一个社区版本,不过那时候使用的人数并不多,直到2016年才慢慢有公司使用,也就是在那个时候我们第一次接触到了React Native,并被它“一次编写,处处运行”的跨平台编程思想所吸引,于是在2017年我出版了人生的第一本书,也就是本书的第1版,并在2020年进行了升级,出版了本书的第2版。

本着与时俱进的思想,如今本书在理论和实战方面都得到了加强,知识体系和架构都进行了升级。相信本书定会给您学习React Native带来帮助和启发。

资源与支持

资源获取

本书提供如下资源:

● 本书项目源代码

● 本书思维导图

● 异步社区7天VIP会员

要获得以上资源,您可以扫描下方二维码,根据指引领取。

提交勘误

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区(https://www.epubit.com/),按书名搜索,进入本书页面,点击“发表勘误”,输入勘误信息,点击“提交勘误”按钮即可(见右图)。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

与我们联系

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们。

如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

关于异步社区和异步图书

“异步社区”(www.epubit.com)是由人民邮电出版社创办的IT专业图书社区,于2015年8月上线运营,致力于优质内容的出版和分享,为读者提供高品质的学习内容,为作译者提供专业的出版服务,实现作者与读者在线交流互动,以及传统出版与数字出版的融合发展。

“异步图书”是异步社区策划出版的精品IT图书的品牌,依托于人民邮电出版社在计算机图书领域30余年的发展与积淀。异步图书面向IT行业以及各行业使用IT技术的用户。

第1章 React Native快速入门

1.1 React Native简介

随着移动互联网的兴起,移动应用开发也逐渐兴起,不过传统的移动应用开发需要同时兼顾多端的开发,这不仅大大降低了开发的效率,也不能适应移动应用高速迭代的需求。为了提高开发效率,同时节约多端开发带来的人力成本,不少公司一直在寻找一种可以高效开发的移动跨平台技术方案。

纵观当前流行的移动跨平台技术方案,无外乎3类。第一类是使用原生内置浏览器加载HTML5的Hybrid技术,具有代表性的有Cordova、Ionic和微信小程序;第二类是先使用JavaScript开发,然后使用原生组件进行渲染,具有代表性的有React Native、Weex和快应用;第三类是使用自带的渲染引擎和自带的原生组件实现跨平台,具有代表性的有Flutter。

抛开陈旧的Hybrid技术,当前讨论的移动跨平台技术方案主要以React Native、Weex和Flutter等为主。不过,从开发效率、渲染性能、维护成本和社区生态等不同方面来看,这几种移动跨平台技术方案各有优劣。总的来说,Flutter的渲染性能是最好的,而从开发效率和维护成本来说,React Native则更优,Weex则由于社区生态的原因基本已经被废弃。

React Native作为目前最为流行的移动跨平台技术方案之一,是Facebook(已于2021年10月更名为Meta)在2015年4月开源的一套移动跨平台技术框架,使用JavaScript作为基本的开发语言,支持在Android、iOS和Web等多个平台上运行。同时,React Native已经被广大的开发者应用在商业项目中,在开源项目托管网站GitHub上,更是获得了大量开发者的关注,如图1-1所示。

图1-1 GitHub上的React Native项目

1.2 React Native环境搭建

在开始React Native应用开发之前,我们需要先搭建好React Native的开发环境,且需要安装或搭建以下辅助工具及环境。

Node.js:React Native需要借助Node.js来创建和运行JavaScript代码。

原生Android和iOS开发环境:由于React Native的运行需要依赖原生Android和iOS环境,因此需要分别搭建原生Android和iOS的开发环境。

其他开发工具:代码编辑器Visual Studio Code或WebStorm、远程调试工具Chrome浏览器等。

下面对前两类辅助工具和环境的操作进行介绍。

1.2.1 安装Node.js

Node.js本身并不是一门开发语言,也不属于任何JavaScript技术框架,而是瑞安·达尔(Ryan Dahl)开发的一个基于Google Chrome V8引擎的JavaScript运行环境。它使用一个事件驱动、非阻塞式I/O(Input/Output,输入输出)模型,让JavaScript具备了开发服务端接口的能力。同时,Node.js提供的npm(node package manager,node包管理器)包管理工具还是全球最大的前端开源库管理系统之一。

由于运行React Native需要Node.js环境的支持,因此,如果还没有安装Node.js,可以从它的官网下载对应操作系统的安装包。推荐下载最新的LTS(Long Term Support,长期支持)版本,因为LTS版本是最稳定的版本,出现问题的概率较低。

下载完成后,双击安装包,然后根据安装向导依次单击【继续】按钮安装即可,如图1-2所示。

图1-2 安装Node.js

安装完成之后,可以使用node -v命令来验证是否安装成功。如果安装成功,系统会显示Node.js的版本号等信息,使用npm -v命令得到npm包的版本信息,如图1-3所示。

图1-3 查看Node.js和npm包版本信息

1.2.2 搭建Android开发环境

由于React Native项目的编译和运行需要依赖原生平台,所以在搭建React Native开发环境前,需要先搭建好原生Android和iOS开发环境。

在搭建原生Android开发环境之前,由于Android项目的开发和运行需要依赖Java环境,因此,如果还没有安装Java环境,可以从JDK(Java语言的软件开发工具包)官网下载操作系统对应的JDK版本然后进行安装。安装完成之后,可以使用java -version命令来验证Java开发环境是否安装成功,并查看其版本信息,如图1-4所示。

图1-4 查看Java版本信息

同时,为了方便后面项目中使用Java的命令行工具,还需要在.bash_profile文件中配置环境变量,如下所示。

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH:.
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.

配置完Java开发环境之后,接下来安装Android开发工具Android Studio和Android开发套件Android SDK。

首先,从Android官网下载最新的Android Studio并安装,安装完成之后,第一次启动它会自动下载Android SDK,下载Android SDK前需要在Android Studio的设置板中配置Android SDK Tools的路径。成功配置Android SDK Tools的路径后就可以下载Android SDK了,如图1-5所示。

需要说明的是,由于React Native的Android环境需要Build-tools 23.0.1及以上版本的支持,因此需要确保本地已经下载了对应的Android SDK版本。

同时,为了方便在项目中使用Android命令行工具,还需要配置Android系统环境变量,如下所示。

export ANDROID_HOME="/Users/mac/Android/sdk"    
export PATH=${PATH}:${ANDROID_HOME}/tools        
export PATH=${PATH}:${ANDROID_HOME}/platform-tools

配置完成之后,可以使用adb shell命令来验证Android环境变量的配置是否成功。

图1-5 下载Android SDK及Android SDK Tools

1.2.3 搭建iOS开发环境

众所周知,开发iOS应用需要macOS操作系统支持,所以如果经济条件允许,最好准备一台Mac计算机。只有这样,才能使用React Native开发可以同时在iOS和Android设备上运行的跨平台应用,发挥React Native跨平台应用开发的优势。

使用React Native开发iOS端的应用时需要Xcode 7及更高版本的支持,如果本地还没有安装Xcode集成开发工具,可以从App Store上下载最新版本的Xcode并进行安装,如图1-6所示。

图1-6 下载并安装Xcode

Xcode必须通过Apple官网或者App Store进行下载,否则容易出现非法代码植入和代码泄漏的风险。比如,2015年9月发生的XcodeGhost非法代码植入事件,就是由开发者使用非官方的Xcode导致的。

同时,React Native项目的原生iOS部分使用CocoaPods来管理第三方依赖库,所以在搭建iOS开发环境前还需要安装CocoaPods库管理工具。如果还没有安装CocoaPods,可以使用下面的命令进行安装,并且我们更推荐使用Homebrew的方式进行安装。

sudo gem install cocoapods 

或者

brew install cocoapods   //推荐

Homebrew是一款macOS平台下的软件包管理工具,支持软件包的安装、卸载、更新、查看等功能。安装完成之后,可以使用pod -version命令来验证是否安装成功,安装成功会输出CocoaPods的版本信息。

需要注意的是,对于Mac M1架构的设备,Cocoapods可能存在一些兼容问题,此时可以尝试运行如下命令进行修复。

sudo arch -x86_64 gem install ffi
arch -x86_64 pod install

1.3 React Native开发工具

1.3.1 Visual Studio Code

“工欲善其事,必先利其器”。一款好的开发工具不仅可以提高开发效率,还能在其他插件的支持下降低程序出问题的概率。由于React Native跨平台应用开发主要使用的是JavaScript语言,所以推荐Visual Studio Code(VS Code)和WebStorm两款前端开发利器。

VS Code是Microsoft于2015年发布的一款免费开源的现代化轻量级代码编辑工具,支持C++、C#、Python、PHP和Dart等开发语言,同时它还支持JavaScript、TypeScript和Node.js等,是一款真正轻量且强大的跨平台开源代码编辑工具。

如果使用VS Code来开发React Native应用,那么需要先安装React Native Tools插件,React Native Tools插件提供了React Native开发所需的环境支持。如图1-7所示,打开VS Code,然后单击React Native左侧的【EXTENSIONS】按钮,在搜索框中输入“React Native Tools”关键字搜索插件,选择该插件并安装。

图1-7 安装React Native Tools插件

除了React Native Tools插件外,在React Native应用开发中,为了提高开发效率,方便代码调试,还需要安装Dash、ESLint、Path Intellisense和Typings auto installer等插件。

1.3.2 WebStorm

除了VS Code工具外,本书也推荐使用WebStorm来开发React Native跨平台应用。WebStorm是JetBrains公司旗下的一款JavaScript开发工具,被前端开发者誉为“Web开发神器”,可以使用它进行Web前端和客户端应用的开发工作。

WebStorm继承了IntelliJ IDEA(Java语言的集成开发环境)的强大功能,支持macOS、Windows和Linux等主流操作系统。同时,新版的WebStorm已经默认添加了对React Native开发环境的支持,WebStorm提供的图形化界面使用户可以很方便地创建、运行及调试项目,如图1-8所示。

图1-8 使用WebStorm新建React Native 项目

当然,不管是使用VS Code还是WebStorm,能够提高开发效率才是最重要的。

1.4 React Native应用示例

1.4.1 初始化项目

React Native支持使用命令行和IDE(Integrated Development Environment,集成开发环境)两种方式来创建项目。其中,使用命令行方式初始化React Native项目如下所示。

npx react-native init RNDemos

需要注意的是,初始化React Native项目时,项目名称不能包含中文、空格和特殊符号,也不能使用JavaScript关键字(如class、native、new等)作为项目名。

同时,React Native在初始化项目时还支持指定版本和项目模板,如下所示。

//指定版本
npx react-native init AwesomeProject --version 0.66.0   
//指定项目模板
npx react-native init AwesomeTSProject --template react-native-template-typescript

当然,除了命令行方式外,我们还推荐使用VS Code或WebStorm等可视化编辑工具来创建React Native项目。

React Native项目创建成功之后,系统还会自动安装项目所需的第三方依赖库。然后,使用VS Code或WebStorm打开React Native项目查看其结构,如图1-9所示。

图1-9 React Native项目结构

在新创建的React Native项目中,有几个重要的文件目录需要说明,如表1-1所示。

表1-1 React Native项目文件目录说明

文件目录

说  明

__tests__

React Native项目单元测试文件

android

原生Android项目文件夹

ios

原生iOS项目文件夹

node_modules

React Native项目的第三方依赖库

index.js

React Native项目的入口文件

package.json

React Native项目配置文件

在React Native应用开发中,我们需要重点关注的是index.js和package.json文件。index.js是应用的入口,也是应用业务的入口;package.json则用于管理工程配置。

接下来,我们打开React Native项目结构下的android和ios文件目录。可以发现,其结构和原生Android、iOS的项目结构是一样的,这也从侧面说明开发React Native应用是需要原生Android、iOS环境支持的。

1.4.2 运行项目

在运行React Native项目之前,需要配置好原生开发环境,即运行iOS应用需要正确安装和配置Xcode、Cocoa Pods,运行Android应用需要正确安装和配置Android Studio和Android SDK Tools。

同时,为了能够正常地运行项目,还需要在项目运行之前启动模拟器或者真机设备。启动模拟器或真机设置后,我们可以使用如下命令来查看可用的设备。

xcrun simctl list devices   //查看可用的iOS设备
adb devices                 //查看可用的Android设备

然后,在项目的根目录下执行如下命令即可启动React Native项目。

//启动iOS版本的项目
yarn ios或者yarn react-native run-ios
//启动Android版本的项目
yarn android或者yarn react-native run- android

上述命令会对项目的原生部分进行编译,同时在后台启动Metro服务对 JavaScript代码进行实时打包处理。当然,Metro服务也可以使用yarn start命令单独启动。如果此命令无法正常运行,可以使用Android Studio或者Xcode打开对应的原生项目来查看错误提示。如果没有任何错误提示,那么运行效果如图1-10所示。

图1-10 运行React Native示例项目

需要说明的是,如果我们的计算机同时连接了多个移动设备,那么在启动项目的时候需要指定运行的设备,如下所示。

yarn ios --simulator "iPhone 12"
yarn android emulator -5554

1.4.3 修改示例项目

为了让大家快速地感受到React Native的魅力,我们打开示例项目lib目录下的main.dart文件,然后修改欢迎语句,如下所示。

const Header = ():Node => (
  <ImageBackground
    accessibilityRole={'image'}
    source={require('./logo.png')}
    style={styles.background}
    imageStyle={styles.logo}>
    <Text style={styles.text}>你好,欢迎使用React Native</Text>
  </ImageBackground>
);

然后,重新运行项目,就可以看到欢迎语句发生了变化,如图1-11所示。

图1-11 修改React Native示例项目

1.4.4 调试项目

调试是软件开发过程中重要的步骤,也是保证软件质量的重要手段。应用调试不仅可以帮助开发者快速地定位软件中存在的问题,还可以帮助初学者快速理解软件功能。

由于React Native项目主要使用React前端语言进行开发,所以调试React Native需要使用Chrome的DevTools,而Chrome浏览器默认集成了这一工具。而且,React Native集成了对Chrome的DevTools的支持,开发者可以很容易地使用该工具调试React Native应用。

使用真机开发时,只需要晃动设备即可打开调试功能。如果开发时使用的是模拟器,那么可以使用快捷键来打开调试功能,Android模拟器调试的快捷键是【Command + M】,iOS模拟器调试的快捷键是【Command + D】。具体如图1-12所示。

需要说明的是,如果使用真机进行调试,那么调试的真机和开发程序的计算机需要处于同一个Wi-Fi网络下,否则将会出现无法连接的情况。

接着,只需要单击屏幕上的【Debug】选项即可开启远端调试功能。开启远端调试功能时,系统会自动打开Chrome浏览器的调试界面,如图1-13所示。

图1-12 打开调试功能

图1-13 Chrome浏览器调试界面

然后,依次单击Chrome浏览器的【菜单】→【更多工具】→【开发者工具】,或者使用快捷键【Command + Option + I】打开调试窗口,如图1-14所示。

图1-14 使用Chrome浏览器调试React Native应用

可以发现,React Native的程序调试和前端程序调试几乎是一样的,如果读者有前端开发的基础,那么React Native开发可以做到快速上手。

接下来,我们将调试面板切换到Sources,然后使用快捷键【Command + O】找到需要调试的文件,在需要调试的地方添加一个断点,再次运行程序即可执行断点调试操作,如图1-15所示。

图1-15 React Native应用断点调试

当程序运行到添加断点的地方时,就会自动挂起。此时,可以在调试面板的右侧获取如下信息:应用的线程状态、变量值、调用栈、全局监听器等。而Chrome DevTools提供的单步跳过、单步进入、跳转到光标等调试操作也可以方便用户查看程序的具体信息,如图1-16所示。

图1-16 Chrome DevTools断点调试步进区

借助Chrome DevTools提供的断点调试工具,开发者可以很方便地查看当前程序运行的状态信息。

除了可开启远端调试功能的Debug选项外,React Native还提供了很多其他有用的选项,如Reload、Enable Live Reload和Enable Hot Reloading等。其中,开启Enable Live Reload选项时,不需要手动触发即可实现动态加载更新;开启Enable Hot Reloading选项时,进行任何代码上的修改均不需要重新启动应用即可看到修改后的效果。

1.5 集成到原生应用

使用React Native从零开始开发一款移动应用是一件很惬意的事情,但对于一些已经上线多年的产品,完全摒弃原有应用的历史沉淀,全面转向React Native是不现实的。因此,使用React Native去统一原生Android、iOS应用的技术栈,把它作为已有原生应用的扩展模块,是目前集成React Native最有效的方式之一。

1.5.1 集成到原生Android项目

首先,在原生Android项目的根目录下执行yarn init命令创建一个名为package.json的空文件。然后,根据提示输入对应的配置信息。命令执行完成之后,会发现原生Android项目的根目录下多了一个package.json文件,该文件就是刚创建的文件。

接着,使用如下命令添加React和React Native运行环境的支持脚本。

yarn add react react-native

执行完命令后,会发现原生Android项目的根目录下多了一个node_modules文件夹,里面包含React Native开发与运行所需的依赖模块,原则上这个文件目录是不能复制、移动和修改的,并且,node_modules文件夹中的内容不需要上传仓库,所以还需要将node_modules文件目录记录到.gitignore文件中。

接下来,使用文本编辑器打开package.json文件,配置React Native的启动脚本,代码如下。

"scripts":{
     "start":"yarn react-native start",
  },

至此,React Native所需的运行环境就配置完成了。此时,package.json文件的全部内容如下所示。

{
  "name":"AndroidDemo",
  "version":"1.0.0",
  "main":"index.js",
  "license":"MIT",
  "dependencies":{
    "react":"^17.0.1",
    "react-native":"^0.66.0"
  },
  "scripts":{
    "start":"yarn react-native start"
  }
}

打开原生Android项目,然后在其根目录下创建一个index.js文件,将它作为React Native模块的入口,代码如下。

import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';
  
class HelloWorld extends React.Component {
     render() {
         return (
              <View style={styles.container}>
                        <Text style={styles.hello}>Hello, React Native</Text>
              </View>
         );
     }
}
  
const styles = StyleSheet.create({
     container:{
         flex:1,
         justifyContent:'center',
     },
     hello:{
         fontSize:20,
         textAlign:'center',
         margin:10,
     },
});
  
AppRegistry.registerComponent('MyReactNativeApp', () => HelloWorld);

接下来,我们使用Android Studio打开原生Android项目,并在app目录下的build.gradle文件的dependencies代码块中添加React Native和JSC(Java Script Core)引擎依赖,如下所示。

dependencies {
    ...
    implementation "com.facebook.react:react-native:+" 
    implementation "org.webkit:android-jsc:+"
}

需要说明的是,如果不指定依赖的版本,那么默认使用的是package.json文件中配置的React Native版本。然后,在项目的build.gradle文件的allprojects代码块中添加React Native和JSC引擎的路径,如下所示。

allprojects {
     repositories {
         maven {
             url "$rootDir/../node_modules/react-native/android"
         }
         maven {
             url("$rootDir/../node_modules/jsc-android/dist")
         }
         ...
     }
     ...
}

然后,打开AndroidManifest.xml清单文件,添加网络权限代码,如下所示。

<uses-permission android:name="android.permission.INTERNET" />

如果需要访问开发者调试菜单,还需要在AndroidManifest.xml清单文件中注册DevSettings Activity页面,如下所示。

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

接下来,新建一个Activity作为React Native的容器页面,并在Activity中创建一个React RootView对象,然后在这个对象中启动React Native应用代码,如下所示。

public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
  
     private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
  
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         SoLoader.init(this, false);
         mReactRootView = new ReactRootView(this);
         mReactInstanceManager = ReactInstanceManager.builder()
                 .setApplication(getApplication())
                 .setCurrentActivity(this)
                 .setBundleAssetName("index.android.bundle")
                 .setJSMainModulePath("index")
                 .addPackage(new MainReactPackage())
                 .setUseDeveloperSupport(BuildConfig.DEBUG)
                 .setInitialLifecycleState(LifecycleState.RESUMED)
                 .build();
         mReactRootView.startReactApplication(mReactInstanceManager, 
"MyReactNativeApp", null); setContentView(mReactRootView); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } }

可以使用Android Studio的【Alt + Enter】快捷键自动导入缺失的语句。BuildConfig是编译时自动生成的,无须额外引入。

由于React Native应用调试还需要打开悬浮窗权限,所以需要在原生Android项目的代码中添加悬浮窗权限逻辑,如下所示。

private final int OVERLAY_PERMISSION_REQ_CODE = 1; 
  
private void requestPermission() {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                      Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                Uri.parse("package:" + getPackageName()));
                      startActivityForResult(intent, 
OVERLAY_PERMISSION_REQ_CODE);
                }
          }
}
  
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                      // SYSTEM_ALERT_WINDOW permission not granted
                }
          }
    }
    mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
}

接下来,我们在AndroidManifest.xml清单文件中注册MyReactActivity,此处我们直接使用MyReactActivity替换MainActivity作为应用的主页面,如下所示。

<activity
        android:name=".MyReactActivity"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
           <action android:name="android.intent.action.MAIN" />
           <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

完成上述操作后,我们在src/main目录下创建一个assets资源文件夹,然后执行如下打包命令。

react-native bundle --platform android --entry-file index.js --bundle-output app/src/main/assets/index.android.bundle --dev false

接着,执行yarn start命令启动React Native所需的服务,然后重新运行原生Android项目即可看到效果,如图1-17所示。

图1-17 在原生Android项目中集成React Native

1.5.2 集成到原生iOS项目

在原生iOS项目中集成React Native的步骤和在原生Android项目中是一样的。首先,需要在原生iOS项目的根目录下创建一个package.json文件,然后添加如下脚本代码。

{
  "name":"RNiOS",
  "version":"1.0.0",
  "main":"index.js",
  "license":"MIT",
  "dependencies":{
    "react":"^17.0.1",
    "react-native":"^0.66.0"
  },
  "scripts":{
    "start":"yarn react-native start"
  }
}

然后,执行yarn install命令安装React Native需要的依赖包。接着,新建一个index.js文件作为React Native部分的入口,代码如下。

import React from 'react';
import {AppRegistry,StyleSheet,Text,View} from 'react-native';
  
class ReactHost extends React.Component {
   render() {
     return (
       <View style={styles.container}>
         <Text style={styles.hello}>2048 High Scores</Text>
       </View>
     )
   }
}
  
AppRegistry.registerComponent('MyReactNativeApp', () => ReactHost);

接下来,在iOS项目的根目录下使用pod init命令创建一个Podfile文件,添加如下依赖包脚本。

# target的名字一般与你的项目名字相同
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/
RCTRequired" pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" pod 'React', :path => '../node_modules/react-native/' pod 'React-Core', :path => '../node_modules/react-native/' pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' pod 'React-RCTActionSheet', :path => '../node_modules/react-native/
Libraries/ActionSheetIOS' pod 'React-RCTAnimation', :path => '../node_modules/react-native/
Libraries/NativeAnimation' pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' pod 'React-RCTVibration', :path => '../node_modules/react-native/
Libraries/Vibration' pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon" pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-
native/ReactCommon" pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/
third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-
podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-
podspecs/Folly.podspec' end

需要说明的是,上面的脚本是启动React Native部分所必需的,并且每个React Native版本依赖的Podfile文件会有细微的差别。完成上述配置之后,使用pod install命令安装所需的依赖包。

接着,使用Xcode打开原生iOS项目,在ViewController.m启动文件中添加如下代码。

- (IBAction)highScoreButtonPressed:(id)sender {
      NSLog(@"High Score Button Pressed");
      NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:
8081/index.bundle?platform=ios"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"RNHighScores" initialProperties: @{ @"scores":@[ @{ @"name":@"Alex", @"value":@"42" }, @{ @"name":@"Joel", @"value":@"10" } ] } launchOptions:nil]; UIViewController *vc = [[UIViewController alloc] init]; vc.view = rootView; [self presentViewController:vc animated:YES completion:nil]; }

执行完上面的代码后,应用会打开React Native的index.js页面,并且从原生iOS项目部分获取的数据也会显示到屏幕上。

最后,使用yarn start命令启动Node.js服务,重新运行原生iOS项目即可看到效果,如图1-18所示。

图1-18 在原生iOS项目中集成React Native

1.5.3 开发机顶盒应用

除了开发移动端的应用外,React Native还支持开发机顶盒应用。要开发机顶盒应用,只需在JavaScript端对代码进行简单的修改即可。

对于Android TV来说,打开原生Android项目的AndroidManifest.xml清单文件,然后添加如下配置。

<application
  ...
  android:banner="@drawable/tv_banner">
    ...
    <intent-filter>
      ...
      <!-- Android TV 横向显示 -->
      <category 
  android:name="android.intent.category.LEANBACK_LAUNCHER"/>
    </intent-filter>
    ...
  </application>

因为机顶盒应用和移动端应用的布局方式是不一样的,所以在JavaScript端需要加入检测设备的代码,然后根据运行的设备调用不同的布局代码,如下所示。

import { Platform } from "react-native";
const running_on_tv = Platform.isTV;

1.6 本章小结

作为目前流行的移动跨平台技术方案之一,React Native不仅兼顾了开发难易程度、性能、成本和复用等产品开发中的诸多因素,还拥有强大的开源社区和开发群体。而且它使用React作为基本的开发语言,也为前端开发者快速上手移动应用开发提供了捷径。

本章主要从React Native简介、环境搭建、开发工具、应用示例、集成到原生应用等方面介绍React Native开发中的基础知识,难度较低,可以快速上手。

习题

一、简述题

1.请简单介绍一下React Native的优点和缺点。

2.请简述React Native的新旧架构,以及新架构在哪方面进行了提升。

3.React Native应用包含哪几个线程,都有什么作用?

4.React Native的Node.js有什么作用?

二、实践题

1.完成React Native环境的搭建,创建并运行示例项目。

2.在原生Android、iOS项目中集成React Native模块,完成简单的跳转。

3.熟悉VS Code和WebStorm等集成开发工具。

相关图书

树莓派开发实战(第3版)
树莓派开发实战(第3版)
深入浅出React Native
深入浅出React Native
Flutter App开发:从入门到实战
Flutter App开发:从入门到实战
React Native移动开发实战 第2版
React Native移动开发实战 第2版
App自动化测试与框架实战
App自动化测试与框架实战
30天App开发从0到1:APICloud移动开发实战
30天App开发从0到1:APICloud移动开发实战

相关文章

相关课程