React Native 与 OC 之间通信那些事儿
来源:互联网 发布:看图猜电影pc软件 编辑:程序博客网 时间:2024/06/05 15:00
React Native用IOS自带的JavaScriptCore作为JS的解析引擎,普通的JS-OC通信就是React Native在OC定义一个模块方法,JS可以直接调用这个模块方法并还可以无缝衔接回调。
https://www.qcloud.com/community/article/607196001489391639?fromSource=gwzcw.107712.107712.107712
具体的接口调用实现方法如下所示:
- 将OC注册进来的模块取出,调用模块中的对应函数,且将参数传入
var RCTVideo = require('react-native').NativeModules.RCTVideo;RCTVideo.addVideoTitle('video title');
- 利用回调参数得到访问OC的函数,并得到其返回值
RCTVideo.RNCallbackEvent('dsb',(error,callBackEvents)=>{ if (error) { console.error(error); } else { AlertIOS.alert('返回值:'+JSON.stringify(callBackEvents)); }});
- 利用回调参数得到访问OC的函数,并得到其返回值
callback函数:第一个参数是一个错误对象(没有发生错误的时候为null),而剩下的部分是函数的返回值。
RCTVideo.RNCallbackEvent('dsb',(error,callBackEvents)=>{ if (error) { console.error(error); } else { AlertIOS.alert('返回值:'+JSON.stringify(callBackEvents)); }});
- 如果想要OC访问JS,我们需要利用 NativeAppEventEmitter组件,利用其addListener进行注册监听
let ocFun = NativeAppEventEmitter.addListener( 'eventName', (para) => AlertIOS.alert('被OC触发','字典数据:\n name:'+para.name+'\n age:'+para.age));
ocFun : 将绑定好的监听事件引用交给此变量保存。
addListener:
第一个参数:事件名
第二个参数:响应函数
注意:利用addListener进行监听,一定要对应有取消监听!
且通常取消监听都在componentWillUnmount函数中进行。如下:
componentWillUnmount(){ ocFun.remove(); }
- 如何用js构建native封装好的本地UI组件
简单地封装一个native封装好的本地视频组建的实现方法如下:
var { requireNativeComponent } = require('react-native');module.exports = requireNativeComponent('RCTVideo', null);
现在这是 JavaScript 中一个功能完整的 native video视图组件了,包括 pinch-zoom 和其他 native 手势支持, 但是我们还不能用 JavaScript 来真正的控制它,所以接下来我们需要给组建添加属性和方法,具体示例如下:
class VideoView extends React.Component { constructor() { this.play = this.play.bind(this); } play = (event) => { if (this.props.play) { this.props.play(event.nativeEvent); } } render() { return ( <View> <RCTVideo {...this.props} style = {styles.fullscreen} /> </View> ) } } VideoView.propTypes = { src: React.PropTypes.string, play:React.PropTypes.func, };var RCTVideo = requireNativeComponent('RCTVideo', VideoView, nativeOnly: { src: true, play: true, })
接下来看看其实现原理,理解react native与OC之间的通信我们首先需要了解模块配置表,接下来对模块配置表进行简单的介绍:
####模块配置表
js如果要调用oc提供的接口方法,OC首先需要向JS传递它所有的模块信息。这里的具体实现方法是OC生成一份模块配置表传给JS,配置表里包括了所有模块和模块里方法的信,具体信息如下所示:
{ "remoteModuleConfig": { "RCTVideo": { "methods": { "play": { "type": "remote", "methodID": 0 } }, "moduleID": 4 }, ... },}
####OC与js之间的调用流程
OC端和JS端分别各有一个bridge,两个bridge都保存了同样一份模块配置表,JS调用OC模块方法时,通过bridge里的配置表把模块方法转为模块ID和方法ID传给OC,OC通过bridge的模块配置表找到对应的方法执行之,以上述代码为例,流程大概是这样(先不考虑callback):
接下来看看JS调用OC模块方法的详细流程,包括callback回调,下面展示的是细化版本的调用流程图:
详细说明下这些步骤:
- 1.JS端调用某个OC模块暴露出来的方法
- 2.把上一步的调用分解为ModuleName,MethodName,arguments,再扔给MessageQueue处理。
在初始化时模块配置表上的每一个模块都生成了对应的remoteModule对象,对象里也生成了跟模块配置表里一一对应的方法,这些方法里可以拿到自身的模块名,方法名,并对callback进行一些处理,再移交给MessageQueue。 - 3.在这一步把JS的callback函数缓存在MessageQueue的一个成员变量里,用CallbackID代表callback。在通过保存在MessageQueue的模块配置表把上一步传进来的ModuleName和MethodName转为ModuleID和MethodID。
- 4.把上述步骤得到的ModuleID,MethodId,CallbackID和其他参数argus传给OC。
- 5.OC接收到消息,通过模块配置表拿到对应的模块和方法。
- 6.RCTModuleMethod对JS传过来的每一个参数进行处理。
- 7.OC模块方法调用完,执行block回调。
- 8.调用到第6步说明的RCTModuleMethod生成的block。
- 9.block里带着CallbackID和block传过来的参数去调JS里MessageQueue的方法invokeCallbackAndReturnFlushedQueue。
- 10.MessageQueue通过CallbackID找到相应的JS callback方法。
- 11.调用callback方法,并把OC带过来的参数一起传过去,完成回调。
######概括一下整体流程如下
整个流程就是这样,简单概括下,差不多就是:JS函数调用转ModuleID/MethodID -> callback转CallbackID -> OC根据ID拿到方法 -> 处理参数 -> 调用OC方法 -> 回调CallbackID -> JS通过CallbackID拿到callback执行
参考文献
- 参开文献:http://reactnative.cn
- React Native与OC之间通信那些事儿
- React Native 与 OC 之间通信那些事儿
- React Native与OC之间通信那些事
- React Js 与 Native 之间的通信
- react-native 与 native组件之间的通信
- React Native 与原生之间的通信(iOS)
- React native和原生之间的通信
- 进程与线程之间那些事儿:
- Java与React Native之间传递参数
- react native 与原生之间的交互
- React Native 与iOS的通信
- React Native与Android通信交互
- 关于 React Native 与 WebView 的通信
- React Native那些事
- React-Native那些事
- React-Native学习十九:组件之间的通信-1
- React-Native学习十九:组件之间的通信-1
- static与构造器之间的那些事儿
- 【剑指offer】二维数组中的查找
- Angular2响应式表单
- explicit用法
- HDOJ 1517 A Multiplication Game
- spring数据库的操作框架
- React Native 与 OC 之间通信那些事儿
- redhat9.0安装gcc详解
- [JZOJ5091]绝版题
- OkHttp实现多线程断点续传下载,单例模式下多任务下载管理器,一起抛掉sp,sqlite的辅助吧
- Eclipse启动时显示“Running Android Lint”错误
- 固态硬盘(SSD)和机械硬盘(HDD)区别对比介绍
- 深入理解java垃圾回收机制----
- PuTsangTo-单撸游戏开发03 碰撞与跳跃瑕疵版
- 排序(3)---归并排序