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

深入理解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日

相关文章

  • js逆向解密之网络爬虫

    下面我将详细讲解关于“js逆向解密之网络爬虫”的完整攻略。这篇攻略包含以下主要内容: 网络爬虫概述 网络爬虫中的JS逆向解密 示例:对bilibili网站使用JS逆向解密进行网络爬虫 网络爬虫概述 网络爬虫是一种利用程序自动抓取网络信息的技术。网络爬虫可以自动访问网络上的网站,获取其中的数据,并将其存储在本地的数据库中供后续分析使用。在网络爬虫的基础上,我们…

    JavaScript 2023年5月28日
    00
  • 利用JavaScript脚本实现滚屏效果的方法

    下面是实现滚屏效果的方法的完整攻略: 利用JavaScript脚本实现滚屏效果的方法 基本思路 我们可以通过监听鼠标或者触摸事件,根据移动的距离来控制页面滚动的位置,从而实现滚屏效果。具体的步骤如下: 监听鼠标或者触摸事件,获取开始移动时的位置和移动的距离。 根据移动的距离计算需要滚动的距离。 利用window.scrollTo()函数来滚动页面的位置。 处…

    JavaScript 2023年6月10日
    00
  • 动态读取JSON解析键值对的方法

    我来详细讲解“动态读取JSON解析键值对的方法”的完整攻略,具体分为以下几个步骤: 1. 获取JSON数据 首先,需要获取JSON数据,可以通过HTTP请求来获取。例如,使用JavaScript中的fetch方法进行请求,代码如下: fetch(‘https://example.com/data.json’) .then(response => res…

    JavaScript 2023年5月27日
    00
  • 关于JavaScript实现动画时动画抖动的原因与解决方法

    关于 JavaScript 实现动画时动画抖动的原因与解决方法,我给你详细讲解。 原因 动画抖动通常是由于浮点数像素值引起的。由于屏幕在每个像素处都是有限制的,所以如果动画的像素值为小数,则会做出近似处理,这可能会导致动画抖动。 举个例子,在动画过程中,由于动画属性的值改变比较频繁,浮点数像素值也变得更加不可避免,浏览器会在每次重绘时尝试平滑过渡,这样就会导…

    JavaScript 2023年6月10日
    00
  • JavaScript原生对象之Number对象的属性和方法详解

    以下是关于“JavaScript原生对象之Number对象的属性和方法详解”的完整攻略。 Number对象的介绍 JavaScript的Number对象代表数字,可以进行数学运算。Number对象是JavaScript中的原始值之一。Number对象有很多属性和方法,可以帮助我们在编写JavaScript程序时,更加方便地操作数字。 Number对象的属性 …

    JavaScript 2023年5月27日
    00
  • 详解JavaScript es6的新增数组方法

    下面就来详细讲解JavaScript ES6新增的数组方法。 简介 ES6为数组添加了很多有用而方便的方法,这些方法可以让开发者的工作更加高效。下面就来简单介绍一下ES6新增的数组方法。 新增方法 Array.from() Array.from()方法用于将类数组对象或可迭代对象转换为数组。此方法的第一个参数是要转换的对象,第二个可选参数是一个映射函数,用于…

    JavaScript 2023年5月27日
    00
  • WebStorm 2017.3最新汉化激活破解及安装教程(附汉化包+原版下载)

    WebStorm 2017.3最新汉化激活破解及安装教程 下载WebStorm 2017.3 首先,到官网下载WebStorm 2017.3,推荐下载Windows版本。下载后双击WebStorm-*.exe开始安装。 安装WebStorm 2017.3 按照提示进行安装,如果需要更改安装路径,可以点击“Custom”按钮进行自定义安装路径。 汉化WebSt…

    JavaScript 2023年6月1日
    00
  • 利用JavaScript获取用户IP属地方法详解

    标题:利用JavaScript获取用户IP属地方法详解 正文:JavaScript作为Web前端开发中的重要语言,常常需要获取用户的IP地址及其所属位置信息。以下是获取用户IP属地的方法详解: 一、使用第三方API接口 使用第三方API接口是获取用户IP属地信息的一种常见方法。可以调用一些免费的IP地址查询API接口,返回结果中包含用户IP的国家、省份、城市…

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