1. RN Compoent 转 Native

1.1. RN

1.1.1. AppContainer

?

1.1.2. AppRegistry

registerComponent

/**
 注册组件

 从组件的 props 获取 runApplication 传过来的参数。

 @param appKey 组件 Key
 @param componentProvider 组件 Class
 */
static registerComponent(appKey, componentProvider, section?)

原生可能通过 appKey 得到相应原生 View

runApplication

/*
 启动 appKey 对应的组件

 @param appKey 组件 Key
 @param appParameters 传给组件的参数
 */
static runApplication(appKey, appParameters)

原生的 RCTRootView 在加载成功后会调用

unmountApplicationComponentAtRootTag

// 注销已经启动的组件
static unmountApplicationComponentAtRootTag(rootTag)

原生的 RCTRootContentView 在注销时会调用

1.2. iOS

1.2.1. RCTBridge

实现部分大部分在 RCTCxxBridge

/**
初始化 RCTBridge

这里会初始化所有原生模块。

@param delegate 获取 bundleURL 的代理
@param launchOptionslaunchOptions 启动参数
*/
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
                   launchOptions:(NSDictionary *)launchOptions;

/**
初始化 RCTBridge 【弃用】

这里会初始化所有原生模块。

@param bundleURL bundle 包
@param launchOptionslaunchOptions 启动参数
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
                   moduleProvider:(RCTBridgeModuleListProvider)block
                    launchOptions:(NSDictionary *)launchOptions;


/**
异步调用原生模块提供的方法

通过回调获取结果
*/
- (void)enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray *)args completion:(dispatch_block_t)completion;

/**
同步执行原生模块里的方法

直接返回结果
*/
- (JSValue *)callFunctionOnModule:(NSString *)module
                           method:(NSString *)method
                        arguments:(NSArray *)arguments
                            error:(NSError **)error;

1.2.2. RCTRootView

// 对应 AppRegistry.registerComponent 的 appKey
@property (nonatomic, copy, readonly) NSString *moduleName;
// 初始化参数,最终会传给 AppRegistry.registerComponent 注册的组件
@property (nonatomic, copy, readwrite) NSDictionary *appProperties;
// JS 加载阶段的 placeholder view,默认为 nil,可以设值
@property (nonatomic, strong) UIView *loadingView;
// 隐藏 loadingView 的延时,默认 0.25
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
// 隐藏 loadingView 的持续时间,默认 0.25
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;

/**
创建有多个 RootView 的工程时用下面的初始化方法

@param initialProperties 初始化参数,最终会传给 AppRegistry.registerComponent 注册的组件
*/
- (instancetype)initWithBridge:(RCTBridge *)bridge
                    moduleName:(NSString *)moduleName
             initialProperties:(NSDictionary *)initialProperties

/**
创建只有一个 RootView 的工程时用下面的初始化方法
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
                       moduleName:(NSString *)moduleName
                initialProperties:(NSDictionary *)initialProperties
                    launchOptions:(NSDictionary *)launchOptions

RCTRootView 加载过程:

  1. RCTJavaScriptDidLoadNotification JS Bundle 下载成功
  2. RCTBridgeDidDownloadScriptNotification JS 加载成功
  3. RCTDidInitializeModuleNotification 每个原生模块加载成功
  4. 所有原生模块加载成功就可以当成功处理。

1.2.3. 过程

  1. RN AppRegistry.registerComponent 注册多个 Component
  2. 初始化唯一的 RCTBridge
  3. 初始化多个包含 RCTRootViewViewController

1.3. Android

1.3.1. ReactRootView

private void defaultJSEntryPoint() {
  // ...
  // 调用 JS 的 AppRegistry.runApplication 方法
  catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
}

1.4. 原生直接调用 RN 的 JS 方法

RN 注册 Class.method 方法

const method = () => {
  // do some thing
}

BatchedBridge.registerCallableModule('Class', {
  method
});

iOS 调用 RN 注册的 Class.method 方法

[bridge enqueueJSCall:@"Class"
               method:@"method"
                 args:nil
          completion:nil];

Android 调用 RN 注册的 Class.method 参考 https://github.com/facebook/react-native/blob/59aada873e13bf0b1f5e3a10cfe9a5a45c28f9fb/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java#L492

String jsAppModuleName = getJSModuleName();
catalystInstance.getJSModule(Class.class).method(jsAppModuleName, null);

1.5. References

results matching ""

    No results matching ""