靠谱 的软件外包伙伴

您的位置:首页 > 新闻动态 > 直播应用app软件开发中React Native的使用实践!

直播应用app软件开发中React Native的使用实践!

2016-06-13 09:48:07

React Native是什么

React Native 的 iOS 和 Android 版本目前是由官方在维护,Windows 版本是微软做了迁移,淘宝有把 React Native 移植到 Web 上,另外还有工程师已经把它移植到了 OS X 上了。所以在将来如果你会 React Native,就会很容易成为一个全端工程师。

React Native 用的是 ReactJS 语法。其他的跨平台方案一般是先编译成中间码再在虚拟机中运行,例如 Java 和 .Net ,React Native 却不太一样,因为跨平台是非常难的,平台视图会有很大差异。React Native 的思路是让我们学习这种开发模式后可以用这套模式去开发任何平台的应用,即所谓的 「learn once ,write anywhere」。但是开发的代码会稍微有些不同,例如在 Web 端会写一些 HTML 的 Tag ,在 React Native 中则会写一些抽象出来的原生组件的 Tag 。

React Native 和原有的 Hybrid 框架有何区别呢?首先,它是用原生组件去渲染的,而不是用 WebView ,后面的优势劣势也是因此产生的。其次,它的响应速度也不像是在手机浏览器里面跑的 WebApp,它所有的页面都是 Native。另外,它的动画也不是 CSS 模拟的,而是一些原生动画,这个则可以给用户带来非常好的体验。

当然 Hybrid 框架也有一些优势,比如你可以用你想用的所有前端库,并且也确实做到了跨平台,但是随着 React Native 的不断进步——几乎支持所有的平台,这个优势正在慢慢地被蚕食。

React Native 本身是一个 UI 框架,它更多的像一个库。原来前端可能都是大的吓人,需要把通讯、MVC 等全部解决了,而 React Native 只是一个 UI ,只需用它来写界面,其他的问题你自己去解决即可。你选择哪种架构,React Native并不关心,它只专注地把 UI 部分做好。当然,这也会带来一些问题,因为所有的东西都是视图,做的时候会带来一些挑战。

直播简介

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 1

知道了 React Native 后,我们来了解下直播。了解直播前,让我们先理性地认识一下什么是视频。视频大家每天都看,但是到底什么是视频呢?其实它是一个封装,主要封装了三部分内容,如图 1 所示。上面的部分是 Metadata ,下面是声音,中间最主要的是图片。它是用一些连续的图片来欺骗我们的眼睛,当超过每秒 24 帧的时候,我们看起来就会是连续的。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 2

直播的模型比较简单,如图 2 所示。由主播发起,推送流到云端,然后其他的人通过搜索来观看直播。直播的协议有很多,比较主流的有 RTMP、HLS。RTMP 协议是 Adobe 公司开发的,HLS 则是苹果开发的,它们的主要区别如图 3 所示。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 3

其中,RTMP 是用的 TCP 长连接,所以它是一个长连接协议。而 HLS 从本质上来讲,是一个播放列表,持续不断地更新这个播放列表,最终会产生一些 ts 的切片文件。直接用苹果的浏览器打开之后就可以看 HLS,有些 Android 也支持,但是 HLS 的延时比较长,超过 10 秒钟。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 4

同时,它们具体的使用场景也有一些不同,如图 4 所示。在即时互动的情况下,我们倾向于选用 RTMP 协议,例如在秀场应用中,如果一个土豪给主播发了一个红包,但是主播 10 秒之后才互动就会很不好。而广播协议 HLS,则比较适用于做点播和回放,例如我们在看一个演唱会的时候,可能所有人在看这个演唱会都是延迟了 10 秒钟,但是你不会关心这 10 秒钟,因为每一秒都延时了 10 秒钟。

一个直播应用需要多大开发量

相信映客、龙珠直播等直播 APP 大家都有用过,但是你是否知道一个直播应用需要多大开发量呢?图 5、图 6 是我们开发的一个最简单的直播应用的核心代码展示。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 5

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 6

我们会发现,一个直播应用核心开发竟然只需 2 行代码。前面我们知道,直播模型就是一个推流和收流。图 5 是推流的代码,里面可以设置推到云端的地址、推流的分辨率、码率率等属性,设置完后就可以推流,推流以后就可以播放了,播放的时候还可以设置播放的地址、硬件码、软件码等属性,如图 6。

上面的那些代码为何如此简单,里面都隐藏了哪些细节呢?其实我们在背后做了很多工作,而且用了不止一种语言。React Native 是 JS 语言,它是跑在 iOS 和 Android 上的。但是我们在做的过程中,并没有用 JS 做视频的编解码,也没有用 JS 去实现 RTMP 的协议,主要原因是一些性能问题无法解决。最终采用的方案是 JS + Objective-C + Java,即在 Android 里使用 JS+Java ,在 iOS 里面使用 Objective-C,然后在最上层用一个统一的 API。对应用层工程师而言是跨平台的,即你在 Android 和 iOS 里面写的代码是完全一样的,但是底层我们会用 Java 和 Objective-C 做一定的适配工作。以某个 APP 为例,图 7 是推流部分,最上面的 Streaming 是用 JS 来写的,下面性能关键的部分是用 Objective-C 来写的,比如推流有一个预览的视图,有一个协议的推流的管理器,然后还有一个编码器。播放部分与推流类似,如图8所示。上面是一个 Preview 的 JS 适配在 Android 的方案,下面基本是用 Native 来写的,有一个播放页面和播放流的管理器,包括是硬解码还是软解码。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 7

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 8

所以总结下来,不管在底层的 React Native 有多少的状态,我们最终都能通过 JS 和 Native Code 把它们隐藏在所有的细节里,最终展现给开发者看的只有一个最终页面和够用的属性,即 Preview View 和 Player View。

API 的设计与调用

React Native 是以 View 为中心的,所以在设计 React Native API 的时候,强制要求我们 API 的设计风格和访问方式统一化,主要有「视图」和「属性」这两个概念,这无疑对 API 设计者的功力要求更高了。

首先来看布局管理,布局管理其实是告诉大家这个界面是什么样的,目前 React Native 支持如下一些属性,如图 9 所示。

从经验来看,这些属性基本上可以满足绝大部分的开发需求了,你可以尽量做一些弹性的布局、按比例的布局,因为你可以拿到设备的整个层高宽度和高度,进而做一些百分比布局。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 9

然后是配置管理,如图 10 所示。所谓的配置管理,就是那些一旦设定就不需要改变的东西,因为你的界面一旦确定了,你是要推哪些流和码率,这些在整个推流过程中是不变的。因此,这个配置是相对比较静态的配置。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图10

后面是状态管理,如图 11 所示。状态显然与配置不一样,因为它是可以变的,例如用户可以切换是否静音或画面大小缩放比例等。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图11

接着是动作管理,如图 12 所示。这部分可能与过去的设计有一些差异,之前在设计 API 的时候,动作一般会用方法来解决。这里实际也是一个状态,因为你的 API 不会触发底层的状态改变。但是它是反过来的,是先声明目前的状态,然后再根据当前的状态去实际的调离底层的方法,是开始推流还是停止推流。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 12

图 13 是事件管理,与原生的 API 也不同。这里可以是一个本地函数或者闭包,当某个事件过来的时候可以调用你的函数。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 13

前面介绍了如何做 API 设计,那么工程师该如何去调用 API 呢?答案是状态驱动,如图 14 所示。首先要在当前的界面初始化一个变量,意味有一个这样的变量表示当前是不是静音,然后在创建 Streaming 的时候,Streaming 的 Muted 状态是等于该变量的,这样它们两个就绑定在一起了。初始化时,Streaming 处于静音的状态,然后比如说有一个按纽的回调方法去触发变量的改变,React Native 发现当前的状态发生改变后,就会把所有的属性做一个 diff,这是 React Native 一个比较核心的性能优化点,diff 后发现 Streaming 的 Muted 属性发生变化,就会通知底层的 Native 代码,这样就完成了静音的操作。开始和停止推流也是类似的,只要把 state 设成某一个状态然后去改变它就可以了。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 14

我们用了这么多代码,它们之间的布局可能会非常不同,那么最终是该如何把这些东西融合在一起,去适配它们呢?React Native 本身是采用了 W3C 的新标准,即弹性盒子,它的方式是设计一些相对的布局,例如你的元素是都靠左,还是都靠右,还是在中间,还是分散它,还是等距离等。当然这只是一方面,它的整个规范是比较复杂的,这里面只简单讲了一个属性,具体可以参考链接(https://demos.scotch.io/visual-guide-to-css3-flexbox-flexbox-playground/demos/)。图 15 是 Flex Box 布局标准的一部分。

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 15

大道至简——React Native 在直播应用中的实践 | 架构师实践日

图 16

图 16 是 Android Streaming View 的一个界面树。我们可以看到它的页面有很多层次,中间还有一个对焦框。其实我们只关心最外面的一层,最终应用开发者使用最外面一层的 View 即可,对里面的视图并不关心。在 Android 中我们一般会用 XML Layout 去布局,但是在设计一个 API 的时候,给用户很多种方式显然是不太合适的。当你给了用户一个 XML,然后说用我们的 API 的时候,在 Android 里面还要再去改 XML,如果对方是一个 Web 开发者,它通过 React Native 技术进入了移动开发领域,看到这个 XML 之后会感觉很慌,因为并不知道这个是什么。同理,iOS 里面也是一样的,里面可能会要用到 Auto Layout。这些都是不太推荐的。所以在 Android 里面,我们是直接用代码进行布局,它的核心界面结构并不是太复杂。iOS 里面也是直接保持了最外层的 View 和里面的 View 大小一致。但最终开发者使用的,都是用 Flex Box 来布局。

在开发直播应用的时候,还有一个比较重要的内容,就是如何优雅地获取和释放硬件资源。我们知道,在 iOS 里面这并不是问题,因为 iOS 会根据你的应用状况去释放和获取资源,但是在 Android 里却可能是个问题。在 Android 里面,你如果在后台录像或录声音会比较危险,这个时候 React Native 比较贴心地提供了类似的方法,你可以去监听主 Activity 的做法,然后对应地在你的视图里面做一些响应,去释放一些硬件。

React Native 应用中的一些坑

如今,React Native 发展得非常迅速,版本升级也是非常频繁。去年大概 10 月份的时候还是 0.14 版本,现在已经是 0.26 版本了,迭代速度非常快,一两周可能就会发一个版本。发新版本时,有的时候可以平滑地升级,但是有的时候会非常地痛苦,那么究竟是升级还是不升级呢?不升级,绑定在某一个版本持续使用,这种选择可能更适用于那种平台本身已经非常成熟的情况。而现在 React Native 的发展速度极快了,导航栏已经发布了三个版本,新的组件在不断地发布,性能也在持续地优化。例如原来是在 JS 的线程里面去执行动画,而 JS 是单线程的,执行动画时会对界面产生一定的影响,所以他们在尝试在其他线程中执行动画。最近还支持了 3Dtouch 等。因此,最好是紧跟 React Native 版本更新,至少不要延迟超过两个版本。

然而升级的过程中,也伴随着诸多不适。

第一个是 React Native 在 0.14 版本以后,整个图片的加载方式都变了。原因是原来的图片加载方式非常草率,基本上是你估计在哪里然后给你渲染出来就好了。但是大家知道在 Android 和 iOS 设备上,会有不同的分辨率大小。后来的版本采用了静态编译的方式来解决这个问题,但是从 0.14 版本往上升的时候,需要你重新做一大堆的事情去手动升级。

第二个是 0.19 版本时,Java 里面的一个 Annotation 的包移动了位置,这个小小的升级却产生了非常大的影响,导致所有的第三方的组件都要改动后重新编译,因为所有第三方的扩展组建都非常依赖 Annotation。这个过程当中,可能一时兴起写了一个组件丢在那儿不维护了,就会导致了大量的第三方库不可用,而这个问题是非常严重的。第三是在你每次升级 Node.js 版本之后,并没有提示要把所有的依赖性文件都删除,这样可能会带来一系列问题,而 React Native 的 issues 列表里面可能至少有 5% 都是因为这个问题导致的。

 

关于:中科研拓

深圳市中科研拓科技有限公司专注提供软件外包、app开发、智能硬件开发、O2O电商平台、手机应用程序、大数据系统、物联网项目等开发外包服务,十年研发经验,上百成功案例,中科院软件外包合作企业。通过IT技术实现创造客户和社会的价值,致力于为用户提供最佳的软件解决方案。联系电话400-0316-532,邮箱sales@zhongkerd.com,网址www.zhongkerd.com


  上一篇   [返回首页] [打印] [返回上页]   下一篇