深入理解React Native核心原理(React Native的桥接(Bridge)

yizhihongxing

深入理解React Native核心原理之桥接(Bridge)

React Native是一种基于React的JS框架,它可以让你使用JavaScript和React的开发方式来构建iOS和Android的原生应用。这些原生应用实际上是通过React Native桥接(Bridge)在JavaScript和iOS/Android平台之间进行通信和交互的。

什么是React Native桥接(Bridge)?

React Native桥接(Bridge)是一种在JavaScript和iOS/Android原生代码之间使用的桥接技术。它的原理是通过Native Module和JavaScript Module之间的相互调用来实现Native与JavaScript之间的通信和交互。

每个React Native应用都有一个JavaScript环境和一个宿主环境(iOS或Android平台)。JavaScript代码运行在JavaScript环境中,宿主环境则运行原生的iOS或Android代码。桥接技术则起到了连接和沟通这两个环境之间的作用。

Native Module和JavaScript Module的交互

Native Module是一种可以被JavaScript端调用的原生组件。React Native提供了一些默认的Native Module(比如Image、TextInput等),同时也可以自定义Native Module来满足个性化需求。在iOS和Android平台中,Native Module通常是用Objective-C/Swift或Java来实现的。

JavaScript Module则是一种可以被Native端调用的JavaScript组件。React Native应用中的大多数代码都是JavaScript代码,而JavaScript Module是构建这些代码的基础。JavaScript Module使用ES6的语法来定义,然后通过ES6的export关键字进行导出。

Native Module和JavaScript Module的交互是通过React Native桥接(Bridge)实现的。JavaScript端可以使用RCTBridgeModule和RCTXXXEventEmitter(比如RCTDeviceEventEmitter)等类来与Native端进行交互。而Native端则可以使用RCTExportModule和RCTEventDispatcher等类来与JavaScript端进行交互。

区分同步和异步通信

在Native和JavaScript之间的通信中,有同步和异步两种通信方式。

同步通信是指Native端和JavaScript端在执行过程中会相互阻塞,直到通信完成之后才会继续执行。这种方式通常用于Native Module返回结果给JavaScript端使用。

异步通信则是指Native端和JavaScript端可以在执行的同时进行通信。通信完成之后,Native端通常会通过回调函数等方式将结果返回给JavaScript端。

一般来说,我们应该尽量避免使用同步通信方式,因为它会严重影响应用的性能和响应速度。

示例一:Native Module调用JavaScript Module

下面我们来看一个实际的例子,演示如何在Native Module中调用JavaScript Module。

首先我们需要定义一个Native Module(这里以iOS为例):

#import "RCTBridgeModule.h"

@interface MyNativeModule : NSObject <RCTBridgeModule>
@end

@implementation MyNativeModule

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(callJavaScriptModule:(NSString *)name params:(NSDictionary *)params) {
  RCTLogInfo(@"Calling JavaScript Module with name %@ and params %@", name, params);
}

@end

在这个Native Module中,我们定义了一个名为callJavaScriptModule的方法,在这个方法中,我们打印出调用信息,然后调用JavaScript Module中的一个方法。

然后我们在JavaScript Module中定义一个方法:

const MyJavaScriptModule = {
  sayHello: function() {
    console.log('Hello from JavaScript Module!');
  },
};
export default MyJavaScriptModule;

这个方法可以通过Native Module中的callJavaScriptModule方法进行调用:

- (void)callMyJavaScriptModule {
  [_bridge.eventDispatcher sendAppEventWithName:@"MyEvent" body:@{@"name": @"MyJavaScriptModule", @"method": @"sayHello"}];
}

在这个代码中,我们通过_bridge.eventDispatcher访问RCTEventDispatcher实例,然后调用sendAppEventWithName方法发射一个事件(即名称为MyEvent的事件)到JavaScript模块。这个事件包含两个参数:namemethod,表示被调用的JavaScript模块的名称和方法名。

我们可以在JavaScript模块中监听这个事件,并做出相应的处理:

import {DeviceEventEmitter} from 'react-native';
import MyJavaScriptModule from '../modules/MyJavaScriptModule';

DeviceEventEmitter.addListener('MyEvent', (event) => {
  if (event.name === 'MyJavaScriptModule' && event.method === 'sayHello') {
    MyJavaScriptModule.sayHello();
  }
});

在这个代码中,我们使用DeviceEventEmitter监听事件(名称为MyEvent),并在事件响应函数中判断事件的参数,如果符合条件(即当事件名称为MyJavaScriptModule,且方法名为sayHello时),就调用sayHello方法。

示例二:JavaScript Module调用Native Module

下面我们来看另一个实际的例子,演示如何在JavaScript Module中调用Native Module。

首先我们需要在JavaScript Module中调用Native Module的方法:

import {NativeModules} from 'react-native';

NativeModules.MyNativeModule.callNativeMethod('Hello', (result) => {
  console.log(result);
});

在这个代码中,我们先使用NativeModules模块从全局React Native变量中获取一个名为MyNativeModule的Native Module。然后我们调用它的callNativeMethod方法,并传入一个名为Hello的参数。

callNativeMethod方法是一个异步的方法,它的第二个参数是一个回调函数,当调用成功并返回结果时,回调函数会被执行,将结果作为参数传入。

然后我们再来看一下在Native Module中实现callNativeMethod方法的代码:

#import "RCTBridgeModule.h"

@interface MyNativeModule : NSObject <RCTBridgeModule>
@property (nonatomic, copy) RCTPromiseResolveBlock resolve;
@property (nonatomic, copy) RCTPromiseRejectBlock reject;
@end

@implementation MyNativeModule

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(callNativeMethod:(NSString *)param resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
    self.resolve = resolve;
    self.reject = reject;
    RCTLogInfo(@"Calling Native Method with param %@", param);
}

- (void)callbackWithResult:(NSString *)result {
  self.resolve(result);
}

@end

在这个Native Module中,我们定义了一个callNativeMethod方法,这个方法用于响应来自JavaScript Module的调用。在这个方法中,我们将传入的参数打印出来,并将resolvereject两个回调函数保存下来。resolve回调函数在调用成功时被调用,reject回调函数在调用失败时被调用。

此外,我们还定义了一个callbackWithResult方法,它用于在Native端完成处理后将结果返回给JavaScript端。

我们需要调用这个方法的实际业务代码放在RCT_EXPORT_METHOD(callNativeMethod:(NSString *)param resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)函数里面,并在完成异步处理后主动调用callbackWithResult函数返回处理结果。

//---------------------------------------------------
// 业务处理代码
//---------------------------------------------------
- (void)doSomethingAsync:(NSString *)param {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 模拟一个异步操作
        [NSThread sleepForTimeInterval:1.0f];
        NSString *result = [NSString stringWithFormat:@"Result from Native, param=%@", param];

        // 完成异步处理后回调
        [self callbackWithResult:result];
    });
}

这个异步处理在Real Native中实际为异步操作,用这种方式能保证RN与Native互相不阻塞。

总结

React Native桥接(Bridge)是React Native应用中Native端和JavaScript端之间通信的关键。了解React Native桥接的机制,有助于我们更好地理解React Native应用的内部工作原理,同时也有助于我们更好地定位问题和解决问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解React Native核心原理(React Native的桥接(Bridge) - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 返回函数的JavaScript函数

    返回函数的JavaScript函数指函数内部定义了一个或多个函数,并将其中一个函数作为返回值。这种方式可以使我们在维护函数时更加容易,同时也可以实现更加灵活的编程。 下面,我们将分别从函数内部定义函数和返回函数两个方面对这种方式进行详细讲解。 函数内部定义函数 在JavaScript中,我们可以在一个函数内部定义另一个函数。例如,如下代码中的outerFun…

    JavaScript 2023年5月28日
    00
  • 一看就懂:jsonp详解

    一看就懂:jsonp详解 什么是JSONP JSONP(JSON with Padding)是一种跨域的数据交互方式。它利用了script标签没有跨域限制的特点,通过动态创建script标签来请求服务器返回数据,并通过回调函数来处理返回的数据。 JSONP的原理 在客户端动态创建一个script标签,其中的src属性指向服务器端数据接口,并在接口地址中指定回…

    JavaScript 2023年5月27日
    00
  • js脚本分页代码分享(7种样式)

    我来为你详细讲解“JS脚本分页代码分享(7种样式)”的攻略。 攻略分析 该攻略主要介绍如何使用JavaScript实现分页功能,并提供了7种不同的样式供选择。具体实现过程分为两部分:前端页面展示和后端数据获取。 前端页面展示:主要是在页面上展示分页的样式和相关的操作功能,通过JavaScript监听用户的操作完成前端展示的相关效果。 后端数据获取:通过Aja…

    JavaScript 2023年6月10日
    00
  • javaScript中Math()函数注意事项

    Math()函数是JavaScript语言中的一个内置对象,提供了很多数学相关的工具方法。在使用Math()函数时,有一些需要注意的细节和注意事项。 1. Math()函数使用注意事项 1.1 获取随机数 获取随机数是Math()函数最常用的功能之一。使用Math()函数生成随机数时,需要注意以下两个问题。 随机数生成公式:Math.random() * (…

    JavaScript 2023年5月28日
    00
  • JavaScript实现网页截图功能

    实现网页截图功能需要使用到JS的API,其中最主要的是使用html2canvas和canvas2image两个JS库,并且需要遵循跨域访问的规则。下面是实现网页截图功能的完整攻略: 步骤一:引入必要的JS库 在html文件中的head中引入下列两个JS库: <script src="https://cdn.bootcdn.net/ajax/l…

    JavaScript 2023年5月19日
    00
  • JavaScript 实现类似Express的中间件系统(实例详解)

    来详细讲解一下“JavaScript 实现类似Express的中间件系统(实例详解)”的攻略。 简介 中间件是实现 Express 等框架功能的核心。本文主要讲解如何通过 JavaScript 实现一个类似 Express 的中间件系统。 实现过程 1. 实现基本的 Application 类 首先,我们需要创建一个 Application 类,表示整个应用…

    JavaScript 2023年5月28日
    00
  • 比较简单的一个符合web标准的JS调用flash方法

    实现将JS调用Flash的方法,通常使用的是Flash提供的ExternalInterface类,以下是实现方法: 1. 在Flash中定义需要调用的方法 首先在Flash ActionScript代码中定义需要被调用的方法,可以在你的Flash项目中新建一个Symbol(如code),在新建的Symbol中将需要的函数注册到ExternalInterfac…

    JavaScript 2023年6月11日
    00
  • javascript知识点详解

    Javascript知识点详解 Javascript是一门广泛应用于Web开发的高级编程语言,它是Web前端技术栈中重要的一环。在这里,我们将详细讲解Javascript的重要知识点。 数据类型 Javascript有7种基本数据类型:null、undefined、boolean、number、string、symbol和object。其中,null和und…

    JavaScript 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部