接ReactNative跨平台开发实践-简易直播demo1
三:实现细节
1.集成ReactNative
官网上已经对安卓与iOS平台集成ReactNative描述的很详细了,在此就仅附上官网地址,按照官网步骤就可以集成到现有的原生APP中了。
官网地址:http://facebook.github.io/react-native/docs/integration-with-existing-apps.html
2.第三方库使用方法
简要介绍下对于本demo中使用到的百度推流端SDK,播放端SDK与融云IM SDK的使用方式。
以iOS端为例:
整个工程是基于cocoapods来开发的,因为引用了第三方库,使用cocoapods方便管理。
pod 'BaiduBCECapture', "~> 2.0"
pod 'BaiduBCEPlayerLSS', "2.0.0"
pod 'RongCloudIM', "~> 2.8.14"
推流SDK:BaiduBCECapture与播放SDK:BaiduBCEPlayerLSS的使用比较简单,根据官网提供的demo中的调用方法,将自己的View(在安卓中则是surfaceView)交给SDK来持有就能实现视频渲染了。
下图则是具体的与第三方SDK的交互流程:
根据上图再看代码就很清晰了。
再简要介绍下融云IM SDK:RongCloudIM的使用方法,基本原理为实现协议RCIMClientReceiveMessageDelegate,接收到消息进入协议方法onReceived,其余例如发送消息的操作都是由单例来完成。
3.(重点)将native组件包装成component暴露给JS的实现过程
首先附上官网中将Native UI Component封装给RN的地址:
iOS:http://facebook.github.io/react-native/docs/native-components-ios.html
Android:http://facebook.github.io/react-native/docs/native-components-android.html
根据前面的设计思路,可以总结出需要封装的类即为持有了Model的原生类,RN层需要在这个原生组件之上放置按钮等控件。
iOS的封装的步骤按照官网步骤即可,但安卓的就要复杂一些,首先明确在安卓中是由ViewGroup来管理一系列的View的,但由于我们是想跟iOS的设计思路保持一致,即在RN中直接使用原生类的component,在其上加控件,那么需要封装的就不能是官网示例中的 SimpleViewManager了,必须是可以管理View的ViewGroup,由于我不会安卓开发,关于这点走了不少的弯路,还是万分感谢安卓的同事的指点。
public class ZYLiveBackGroundViewManager extends ViewGroupManager
暴露给RN的方法:
1.无需回调的方法:RCT_EXPORT_METHOD(),如界面上的返回按钮就无需回调,这个按钮直接返回设置页,无论结束推流或播放停止时是成功还是失败都会返回,所以无需将其设置为回调方法。
2.需要回调的方法:RCT_REMAP_METHOD(),如推流界面的控制摄像头方向,设置美颜,设置闪光灯以及开启推流等按钮都需要知道是否操作成功,若操作成功更改界面,来提示用户操作成功,这类需要更新UI的方法就需要回调。
具体实现方法附上官网地址:
iOS:http://facebook.github.io/react-native/docs/native-modules-ios.html
Android:http://facebook.github.io/react-native/docs/native-modules-android.html
这里值得注意的是RN在设计的时候,无论是iOS还是安卓,只要是原生封装暴露给RN的component,都已经实现了桥接协议:
iOS:
@interface RCTViewManager : NSObject
android:
...
public abstract class ViewGroupManager
extends BaseViewManager
...
...
public abstract class BaseViewManager extends ViewManager
...
...
public abstract class ViewManager extends BaseJavaModule
...
这样做的原因应该去看下源码才能理解了,但对我们来说,本身已经暴露成功的Native UI Component就已经可以当成Native Module来使用了。所以,关于module的方法都可直接写在这个component中。
使用方法如下,以iOS中的推流层为例:
nativeStreamView.js
module.exports = requireNativeComponent('ZYLiveBackGroundView', null);//将原生封装的Component暴露出来
streamView.js
import ZYLiveBackGroundView from './nativeStreamView';//获取原生暴露的Component
var myModule = NativeModules.ZYLiveBackGroundViewManager;//获取原生暴露的module,其实都是从iOS的ZYLiveBackGroundViewManager这个类中获取的
...//component的使用:
...
...//module的使用
myModule.onBack();
...
介绍完JS调用原生类后再介绍下原生调用RN的实现,上诉基本是JS来调用原生的控件或方法的,但由于加入了聊天室的功能,融云IM SDK是用原生来实现的,当收到新的消息是,SDK的回调也仅限于原生类,而我们需要在界面上显示收到的这个消息,所以需要在原生收到消息时告知JS来更新界面,这也叫作消息分发。
附上官网实现方法:
iOS:http://facebook.github.io/react-native/docs/native-modules-ios.html#sending-events-to-javascript
Android:http://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
首先我去查找了RCTEventEmitter这个消息分发类,发现这个类与RCTViewManager无关,所以没法再在同一个原生类中实现消息回传RN了,只能新建一个专门用于实现调用JS的类。
iOS ,Android:
IMCloud
具体的使用方法官方文档里已经描述的很清楚了,这里就不重复了,直接看代码就明白了。
四.打包
无论是iOS打包或安卓打包都需要将JS文件与图片文件打包至bundle中,引入工程,但官网中并未提及这点(略坑),所以简要说一下打包的步骤。
iOS打包步骤:
1.打包命令:到项目根目录下执行
react-native bundle --entry-file ./index.ios.js --bundle-output ./ios/index.ios.jsbundle --platform ios --assets-dest ./ios --dev false
输出文件也可不放到iOS工程下,然后回到Xcode中,添加刚刚生成的
idex.ios.jsbundle与assets文件,其中assets的添加方式要选为Create Folder Reference,然后将Scheme修改为release,获取jsbundle的方式改为:
//打包后获取离线bundle
jsCodeLocation = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"index.ios.jsbundle" ofType:nil]];
就可以打包上传iOS应用了。
安卓打包步骤
参考:
http://www.jianshu.com/p/61e27d9b02f2