react native通信机制(还需深入学习,目前只是简单了解),调用原生组件

本文深入解析React Native中原生模块与JavaScript的通信机制,包括JStoNative的实现方式,如block与JSExport协议,以及React Native如何自定义通信机制。同时,介绍了在iOS与Android平台上创建与调用原生组件的具体步骤。

一、原生模块

首先理解原生:https://reactnative.cn/docs/native-modules-android/

二、通信机制

  • RN 整体结构以及关键类的类图

RN 最大的优势在于跨平台、热更新。因此,RN 库本身也需要在多个平台(iOS、Android)上运行,从上图可知,在 RN 中 C++与JS部分的实现为多平台共用,在此基础上再分化为各平台实现。

  • 用Xcode打开项目,其中,iOS 平台特有的实现(Objective-C、C++)主要集中在 React 下,以C++语言实现的共有部分在 ReactCommon 下:

  • 用vscode等软件,打开项目,JS侧与本文关系紧密的内容主要集中在node_modules下的具体路径下,如下图所示:

  • 关键类及其间的关系:

如上图:

RCTBridge与RCTCxxBridge属于 iOS 平台特有,前者是 RN 对业务层接口(图中其他类都属于内部类,业务层无感知),具体工作在其子类RCTCxxBridge中完成;
整个 RN 的核心在跨平台的 C++层,其中很多类的功能从其名称即可略知一二,后文也会有详细的描述;
在 RN 中肯定少不了 JS 的支持,从上图可知,JS 与 Native 的通信发生在 JavaScript 与 C++间,这也是本文分析的重点。
说到通信,无外乎 JS to Native、Native to JS,本篇我们重点分析JS to Native。

  • JavaScript—>Native

实现 JS to Native 的通信,主要有两条途径:

block——在 RN 这样复杂的应用场景中block显得有些力不从心;
JSExport协议——通过实现该协议可以向 JS 曝露 Native 接口(但不具备跨平台能力)。
因此,RN 并没有使用 JavaScriptCore提供的这两种方式,而是自己实现了一套通信机制。
我们先从一个简单的例子入手:CalendarManager封装了 iOS 平台的日历控件,供 JS 调用。

// CalendarManager.h
#import <React/RCTBridgeModule.h>

@interface CalendarManager : NSObject <RCTBridgeModule>
@end
// CalendarManager.m
@implementation CalendarManager

// To export a module named CalendarManager
RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location) {
    RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}
@end

我们知道,要将 Native module(类、接口)曝露给 JS,module需要实现RCTBridgeModule协议,并且在实现中要插入RCT_EXPORT_MODULE宏。具体曝露的方法也需要通过RCT_EXPORT_METHOD宏定义。

// JS
import { NativeModules } from 'react-native';
var CalendarManager = NativeModules.CalendarManager;
CalendarManager.addEvent('Birthday Party', '4 Privet Drive, Surrey');

此时,在 JS 中就可以通过NativeModules.CalendarManager.addEvent(...)方式调用 Native 接口了。

  • React Native调用ios原生组件

1.React Native链接原生库

1.1安装

npm install 某个带有原生依赖的库 --save

1.2链接原生依赖

react-native link

1.3手动链接

如果该库包含原生代码,还需要进行手动链接。在库的文件夹下有一个.xcodeproj文件,将文件拖到你的Xcode工程下(通常拖到Xcode的Libraries分组目录下)

1.4导入库

在项目上依次选择[Targets]->[Bulid Phases]->[Link Binary With Libraries]添加第三方类库生成的静态链接库即可

1.5为项目添加查找路径

选择[Targets]->[Build Settings]->[Search Paths]->[UserHeader Search Paths],在参数中加入第三方类库的头文件路径即可,可以是绝对路径(如/Users/libpath),也可以是相对路径(如$(...)/Users),如下图所示

  • React Native调用Objective-C创建的原生组件

1.创建一个子类:命名为"视图名称+Manager"。最好避免使用RCT前缀,除非你想把你的组件推送给官方使用

2.添加RCT_EXPORT_MODULE()标记宏:让模块接口暴露给JavaScript.

3.实现-(UIView*)view方法:创建并返回组件视图。

4.封装属性与事件传递

  • React Native调用Android原生组件

1.编写原生UI组件

1.1创建子类,实现原生UI管理

1.2创建原生UI管理类,并向系统注册原生UI管理类

2.编写JavaScript端实现

2.1建立私有的JavaScript文件,实现React Native端组件

就是平常写的js文件,此处就不做详细介绍

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值