2015年3月26日,Facebook公司对外正式发布了React Native——使用React框架跨平台开发原生移动应用的开源技术框架。开发者可以使用React Native高效地开发运行于Android与iOS操作系统的应用程序。它的设计理念是:使用ReactNative开发,既拥有Native的良好人机交互体验,又保留了React框架的开发效率。
React框架不追求所谓的“一次编写,随处运行(Writeonce, run anywhere.)”。React认为不同的平台应该有不同的外观、感觉、功能等。开发者仍然需要为不同的平台去做一些额外的工作。React把不同平台的能力分为跨平台通用能力与平台特色能力,这样应用程序的代码也分成了跨平台部分与平台特色部分。React把这个方案叫作“一次学习,随处编写(Learnonce, write anywhere.)”。
在React Native发布的短短5个月里,就有60多个使用React Native技术开发的APP在苹果软件商店上线。开发者在尝试后对ReactNative赞不绝口。它究竟有哪些优点呢?
◆ ◆ ◆
一次学习,随处编写
在iOS与Android这两个操作系统上实现统一的开发框架,一份代码支持两个操作系统在历史中已经证明是非常困难的。React Native提出了“Learn once,write anywhere.”。使用React Native可以为这两个操作系统开发应用程序,但不同平台上的代码根据平台会有一些微小区别,但开发思路是相同的。只需要根据平台进行一些代码调整,有经验的开发人员进行这种调整的速度非常快。React Native开发小组没有狂妄地喊出“Writeonce, run anywhere.”,但在UI开发上,React Native差不多已经做到了这一点。
◆ ◆ ◆
混合开发
混合开发是React Native的另一个重要特性。ReactNative允许开发者在React Native擅长的领域使用React Native开发,而在ReactNative不能实现的领域或者已经有原生代码实现好的领域直接使用原生代码。React Native代码开发的模块与原生代码开发的模块可以双向通信、无缝衔接。这使混合开发变成了件很轻易的事。
很多读者不是很熟悉混合开发这个概念,在这里详细说明一下。混合开发可以分为3种情况:
- UI界面由React Native开发,但UI事件处理由原生代码来执行
举个简单的例子。在React Native开发的界面上有让用户输入用户名与密码的UI控件,还有一个登录按钮。用户点击登录按钮后,ReactNative组件将用户输入的用户名与密码传给原生代码编写的登录模块(在Android上,用Java语言开发;在iOS上,用Objective-C或者Swift语言开发),让原生代码执行登录操作。原生代码通过互联网向网络侧的服务器发送登录消息,并等待服务器回应。在服务器回应后,原生代码再将收到的回应中的登录成功与否,以及其他一些需要UI展示的数据传递给React Native组件,React Native组件接收原生代码传来的数据,解析这些数据并执行UI界面更新,向用户展示相关信息。
- 将原来使用原生代码实现的UI小部件包装成React Native的自定义组件
Widget在移动应用程序开发中被广泛使用,它们有官方发布的,也有第三方开源的,还有开发者自行开发的。React Native支持将这些Widget包装成React Native的自定义组件,然后就可以在ReactNative代码中方便地使用了。
- 应用界面在React Native开发的界面与原生代码开发的界面间切换
在某些情况下,我们希望使用原生代码开发的界面,比如某个界面,在原来的版本中已经开发好了,或者希望在已经用原生代码开发好的项目中加入一些用React Native开发的新界面。混合开发可以做到让应用界面流畅自如地在这两种界面间切换,用户对此不会有任何感知。
我们可不可以用原生代码来开发UI界面,让React Native模块处理UI事件呢?理论上是可以的,但很少有人这么干。因为ReactNative的强项就是UI开发,在混合开发中,能用React Native开发的界面,优先用ReactNative开发。
提到混合开发,不得不提到另一个分支:在手机上使用WebView来呈现部分UI界面。使用WebView开发比较灵活,能沿用全部Web开发的习惯,比如React.js的各种好处和Web的快速迭代流程。但因为所有的渲染都由Web相关技术来完成,使用WebView无法得到真正原生的用户体验,并且WebView无法做到与原生代码双向通信、无缝衔接。React Native不排斥WebView开发,并且为WebView提供了相应的组件,可以在ReactNative中实现部分界面通过WebView呈现。
◆ ◆ ◆
高效的UI开发
对于移动应用开发来说,在单个平台上,UI部分开发工作量占移动应用开发总工作量的比重至少是50%。对于追求界面美观、使用方便、容易上手的移动应用来说,这个比例会提高到70%左右。再考虑到很多应用都需要兼顾Android与iOS两个平台,UI开发的工作量又被放大了1倍。
在这个时候,使用React Native开发的优势就显露无遗了。使用ReactNative开发移动应用的UI界面比使用原生语言快捷高效,再考虑到至少90%的移动应用界面都可以使用React Native开发,一份代码适配Android与iOS两个平台,这相当于减掉了一个开发平台上至少50%的工作量。开发者找不到任何理由不使用ReactNative开发移动应用。
虽然React Native可以实现很多UI之外的功能,但开发UI部分绝对是React Native的强项。这体现在独特的UI实现框架、组件化开发、 跨平台移植代码迅速、自动匹配不同屏幕大小的手机这4个方面上。
◆ ◆ ◆
高效的UI调试
在原生开发过程中,开发者的每一次改动(即使改动的元素非常小,如一个单词,或者一个位置)都需要经历重新编译和构建,然后把安装包上传到手机的过程,这使得开发者在做很多工作时变得非常缓慢,尤其是当一个大工程的编译特别慢时。
使用React Native开发,修改了代码后立刻可以在手机上看到效果,没有重新编译启动程序所需要的时间。并且可以打开一个Chrome窗口,所有的代码都移到Chrome里面运行,断点调试、单步调试、调用栈追踪这些常用的调试方法都可以进行操作。
◆ ◆ ◆
学习门槛低、开发难度低
看到技术大牛们的巨著都是厚厚的一本,笔者也东施效颦,非常努力地尝试着把这本书写得厚些,但本书还是这么薄!从这点读者就应当知道,使用React Native开发的难度实在很低。下面还是总结一下为什么使用React Native开发的难度低。
- 开发语言简单
React Native使用ECMAScript2015(虽然它穿了件很华丽的“马甲”,但我们还是一眼就认出来它就是JavaScript)语言(也简称为ES 6),以及自创的JSX语言(通俗些说,就是在JavaScript中加入一些标签化的XML)来进行开发。JavaScript是一门使用很广泛的语言。相对于目前手机开发人员不足的情况,JavaScript开发人员却很多。经过简单的学习,没有移动应用程序开发基础的JavaScript开发人员就能使用ReactNative进行移动应用程序的UI与部分业务逻辑的开发了。
对于没有JavaScript知识背景的手机APP开发人员,只需要用几天时间熟悉JavaScript的基本语法后就可以使用ReactNative进行开发。
JavaScript是一门很特殊的语言,它很简单但也可以非常复杂。React Native从一开始就注意到了JavaScript的不足之处,要求在React Native开发中使用JavaScript的“严格模式”,并且采用更先进的ECMAScript 2015,能够做到取其精华,去其糟粕。
而React Native使用的JSX语言也是非常简单的,简单到本书不会有专门的章节去讲解它的语法。读者只要一个一个例程从浅入深地学下去,不知不觉间,就已经掌握JSX语言了。
- 语法接近自然语言
React Native开发中的函数名、变量名都采用类似于自然语言的命名法,便于记忆。这种代码,语句的含义基本上可以直接推断与理解。因此学习简单,容易上手。示例详见代码1-1。
- 积木式UI开发
使用React Native开发UI时,是一种类似于搭积木的方式。不论是设计还是实现,通过React Native框架都能做到逻辑结构清晰、开发难度低、可读性高、后期修改维护方便。
◆ ◆ ◆
开发软硬件要求低
使用React Native开发对软硬件要求低,这意味着开发者不需要再掏钱购买电脑硬件与相关软件。React Native开发用软件都是可免费下载、安装使用的正版软件,部分是开源软件。对硬件要求也不高。
◆ ◆ ◆
使用React Native开发的代价
为了得到React Native开发的优点,使用ReactNative开发的APP也需要付出一些代价。代价体现在三个方面上。
- 内存消耗略大
使用React Native开发的程序运行所需的内存比原生代码开发的程序略多。会多多少,没有人认真分析过,笔者也不打算认真分析。
为什么没人愿意分析内存消耗情况呢?因为现在是手机硬件配置已经很强,并且还会越来越强的时代。在笔者写本书时,市场上700元级的入门Android,手机内存配置都达到了2GB,1500元级的中低端手机内存配置达到了4GB。手机用户基本上感觉不到应用程序多占了几十兆内存。某些知名购物、支付移动应用APP在运行时使用的内存已经达到了500MB左右,但根本就没有听到用户对此有任何抱怨。用吧,用了500MB内存,也没有给用户带来任何损失;不用那么多内存,也不能给用户省下一分钱。
开发者开发调试时,React Native项目通常运行在“开发模式”下,这时最简单的Hello World程序会比原生代码的HelloWorld程序多用20MB内存,这是正常的。当使用发布模式编译项目后,React Native项目占用的内存会比开发模式小很多,最简单的Hello World程序会与原生代码的Hello World程序消耗的内存相差不大。
- 运行速度
同样一个应用程序,让一个原生语言开发高手用该手机原生语言开发出来的版本比使用React Native框架开发出来的版本运行速度要略快。但如果只是普通的开发者,因为React Native框架的先进性,使用ReactNative开发出来的版本的运行速度与原生语言开发出来的版本差别不大,甚至会更快一些、Bug更少一些。
使用React Native开发的代码的运行速度比原生代码略慢。速度慢的缺点可以通过两方面来弥补。一是普通的功能(如UI展示、HTTP请求等),React Native实现的速度比原生代码慢,但用户感觉不出来,因此不需要加快。比如显示一个页面,原生代码用10ms完成,React Native代码用了11ms,这对用户来说没有区别。再比如从网络获取数据,这个操作耗时的大头是网络传输时延,用什么语言实现对加快获取都没有帮助。二是核心的功能,通过原生代码来开发,也就是混合开发移动应用程序。
需要特别指出的是,开发者开发调试时,React Native项目通常运行在“开发模式”下,因为有很多特殊的任务需要执行(例如:验证属性类型,产生各种调试信息与警告信息,显示这些信息),代码的运行速度要比“发布模式”下的代码运行速度慢。
- 安装包比原生代码安装包大
使用React Native开发的程序体积比原生代码大。不论是安装包的大小,还是安装后所需的空间都比原生代码编写的程序要大。这勉强算是一个使用React Native开发的代价吧。现在手机存储容量通常64GB,还可以通过存储卡扩充,因此这个代价微不足道。
◆ ◆ ◆
为什么React Native尚未流行
看到这里,估计很多读者都会想既然React Native这么好,为什么还没有开始流行呢?你不会是在“坑儿”我们吧!
React Native尚未流行的原因有两个。第一个原因是React Native于2015年3月发布时就说目标是要支持两大主流手机平台,但直到2015年11月6日放出的0.14.0版本才正式支持Android平台。这是React Native的一个重大里程碑。从这一天起,它才是真正的跨平台开发框架。它的出现时间还不长。
第二个原因是主要原因。React Native对Android的支持正越来越好,但它还是需要一个提高的过程。在初期,React Native对手机配置较高、Android操作系统版本高于5.0的Android手机的支持比较好。而对Android操作系统低于5.0的Android手机的支持还有待完善。也就是说,在2016年年初,使用React Native框架开发Android移动应用程序在老手机上运行还是会遇到问题。
但移动应用开发总是向前发展的,当读者看到这本书时,应当是2016年年中,读完这本书,开始用ReactNative框架开发应用的时间应当是2016年第三季度。到了那个时候,一方面是React Native对Android低版本手机支持会更好;另一方面也得益于Android手机的廉价,它的更新速度快,那时低版本Android手机已经不会再是市场保有量的主流。所以到了2016年年底,使用React Native框架进行跨平台移动应用开发必然会流行起来。不仅是流行起来,而且是成为商业移动应用开发的主流方式。