美文网首页
React Native同步调用Native方法 RCT_EXP

React Native同步调用Native方法 RCT_EXP

作者: sea_biscute | 来源:发表于2018-12-10 21:44 被阅读99次

    JS调用Native

    我们知道,在React Native中,经常需要JS和native交互,在项目RN化的初期,我们在通过JS端编写完页面后,往往还需要调用Native端的方法或属性,来实现一些逻辑交互.
    这里我们就介绍一下,JS端调用Native方法的几种情况.

    异步方法调用

    React Native提供了组件(Module)的概念,Native通过遵守协议<RCTBridgeModule>,实现RCT_EXPORT_MODULE()方法来输出组件.
    需要注意的是,该类内的属性和方法,模式是不会输出到JS端的,必须单独声明.
    输出方法使用RCT_EXPORT_METHOD()来实现.默认在异步线程调用,可以通过- (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); }去回归主线程.
    如果想拿到返回结果,可以使用callback的方式,

    RCT_EXPORT_METHOD(getCacheSize:(RCTResponseSenderBlock)callback){
    callback(@[[NSNull null], @(cacheSize)]);
    }
    

    在JS的使用为

    import { NativeModules } from 'react-native'
    const SettingTool = NativeModules.RNSettingTool
    SettingTool.getCacheSize((error, events) => {
              if (error) {
                  console.error(error)
                } else {
                  this.setState({cacheSize: events.toFixed(2)})
                }
     })
    

    这种方式,每次在使用时都需要实现callback的函数,并且无法做同步调用

    同步方法调用

    RN提供了一个同步调用的方法RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(),直接在方法内return 返回值,在前端通过appVersion = PXUserInfoTool.appVersion()的方式来获得,下面我们讨论一下这个方法的内部实现.

    RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD()
    通过宏定义我们可以看到,同步输出方法,最终是生成了一个RCTMethodInfo并且返回.我们看一下RCTMethodInfo,是一个结构体定义.

    typedef struct RCTMethodInfo {
      const char *const jsName;
      const char *const objcName;
      const BOOL isSync;
    } RCTMethodInfo;
    

    继续通过RCTMethodInfo内部的isSync参数的使用情况,我们知道在- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments方法内部用到了.
    这个方法是,JS端在调用Native代码时触发的方法,继续查看.

    在JS端的实现是在NativeModules.js内部,在function genMethod(moduleID: number, methodID: number, type: MethodType)内通过判断三种调用方式实现的.
    方法调用分为: Promise, sync, 普通方法.
    sync在客户端的调用,是在JSCExecutor.cpp内的JSValueRef JSCExecutor::nativeCallSyncHook( size_t argumentCount, const JSValueRef arguments[])方法,
    最终调用到了RCTNativeModule.mm内的MethodCallResult RCTNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic &&params)方法,
    进一步,RCTModuleMethod.mm内的- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments方法.

    全部都是同步执行的,并且注意**手动指定methodQueue对sync方法无效
    **

    相关文章

      网友评论

          本文标题:React Native同步调用Native方法 RCT_EXP

          本文链接:https://www.haomeiwen.com/subject/chbdhqtx.html