React Native 原生开发指南

写在前面

React Native (RN) 是一个用于构建跨平台移动应用的框架。它允许开发者使用 JavaScript 和 React 来编写应用程序,并将其转换为原生代码。虽然 RN 提供了许多内置的组件和 API,但有时候你可能需要访问原生平台的特定功能或性能优化。为此,RN 提供了多种方式来桥接原生平台能力,包括使用 Turbo 模块、C++ 实现跨平台的原生模块、自定义 C++ 类型和 Fabric 原生 UI 组件。

本文将详细介绍这些方法,并提供一些示例代码和实践建议。

桥接原生平台能力

RN 的核心思想是将 JavaScript 代码转换为原生代码。然而,并不是所有的原生功能都可以直接在 JavaScript 中使用。为了解决这个问题,RN 提供了一个桥接机制,允许你在 JavaScript 和原生代码之间传递数据和调用方法。

Native Module

Native Module 是 RN 中最基本的桥接方式。它允许你在原生平台上编写代码,并将其暴露给 JavaScript。要创建一个 Native Module,你需要在原生平台上编写相应的代码,并在 JavaScript 中使用 NativeModules API 来访问它。

以下是一个简单的示例,演示如何在 iOS 平台上创建一个 Native Module,并在 JavaScript 中使用它:

Objective-C

// MyNativeModule.h
#import <React/RCTBridgeModule.h>@interface MyNativeModule : NSObject <RCTBridgeModule>@end// MyNativeModule.m
#import "MyNativeModule.h"@implementation MyNativeModuleRCT_EXPORT_MODULE();- (dispatch_block_t)sayHello:(NSString *)name callback:(RCTResponseSenderBlock)callback {NSLog(@"Hello, %@", name);callback(@[@"Hello, ", name]);return ^{NSLog(@"Goodbye, %@", name);};
}@end

在这个示例中,我们定义了一个名为 MyNativeModule 的 Native Module,它有一个名为 sayHello 的方法,接受一个字符串参数 name,并在控制台中打印出一条欢迎消息。同时,它还返回一个闭包,用于在调用结束后打印出一条再见消息。

JavaScript

import { NativeModules } from 'react-native';const { MyNativeModule } = NativeModules;MyNativeModule.sayHello('John', (result) => {console.log(result); // 输出:["Hello, ", "John"]
});

在这个示例中,我们首先导入了 NativeModules API。然后,我们使用 MyNativeModule 对象来调用 sayHello 方法,并传递一个字符串参数 name 和一个回调函数。回调函数将接收到一个数组作为参数,包含了欢迎消息的前缀和 name 的值。

Native UI Component

除了 Native Module,RN 还支持 Native UI Component。Native UI Component 允许你在原生平台上编写自定义的 UI 组件,并将其嵌入到 RN 应用程序中。

以下是一个简单的示例,演示如何在 Android 平台上创建一个 Native UI Component,并在 JavaScript 中使用它:

Java

// MyNativeComponent.java
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.JSApplication;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;public class MyNativeComponent extends SimpleViewManager<MyNativeView> {public static final String REACT_CLASS = "MyNativeComponent";@Overridepublic String getName() {return REACT_CLASS;}@Overrideprotected MyNativeView createViewInstance(ThemedReactContext context) {return new MyNativeView(context);}@ReactProp(name = "text")public void setText(MyNativeView view, String text) {view.setText(text);}
}// MyNativeView.java
import android.content.Context;
import android.widget.TextView;public class MyNativeView extends TextView {public MyNativeView(Context context) {super(context);}public void setText(String text) {super.setText(text);}
}

在这个示例中,我们定义了一个名为 MyNativeComponent 的 Native UI Component,它有一个名为 text 的属性,用于设置文本内容。同时,我们还定义了一个名为 MyNativeView 的原生视图类,用于显示文本内容。

JavaScript

import React from 'react';
import { View, Text } from 'react-native';
import { MyNativeComponent } from 'react-native';const App = () => {return (<View><MyNativeComponent text="Hello, World!" /></View>);
};export default App;

在这个示例中,我们首先导入了 MyNativeComponent。然后,我们在 App 组件中使用它,并设置了 text 属性的值。

Turbo 模块

Turbo 模块是 RN 中的一种新型的原生模块,它可以在不需要 JavaScript 线程的情况下直接在原生线程上执行代码。这样可以大大提高性能,尤其是在处理大量数据或进行复杂计算时。

以下是一个简单的示例,演示如何在 iOS 平台上创建一个 Turbo 模块,并在 JavaScript 中使用它:

Objective-C

// MyTurboModule.h
#import <React/RCTTurboModule.h>@interface MyTurboModule : NSObject <RCTTurboModule>@end// MyTurboModule.m
#import "MyTurboModule.h"@implementation MyTurboModule- (void)add:(double)a b:(double)b resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {double result = a + b;resolve(@[ @(result) ]);
}@end

在这个示例中,我们定义了一个名为 MyTurboModule 的 Turbo 模块,它有一个名为 add 的方法,接受两个数字参数 ab,并返回它们的和。

JavaScript

import { NativeModules } from 'react-native';const { MyTurboModule } = NativeModules;MyTurboModule.add(1, 2).then((result) => {console.log(result); // 输出:3
});

在这个示例中,我们首先导入了 NativeModules API。然后,我们使用 MyTurboModule 对象来调用 add 方法,并传递两个数字参数。由于 add 方法是异步的,我们使用 then 方法来处理结果。

使用 C++ 实现跨平台的原生模块

如果你需要在 RN 应用程序中使用一些高性能的原生库或算法,可能需要使用 C++ 来实现跨平台的原生模块。RN 提供了一个名为 react-native-cxx 的库,用于简化这个过程。

以下是一个简单的示例,演示如何在 RN 应用程序中使用 C++ 实现的原生模块:

C++

// MyNativeModule.h
#include <react-native-cxx/JSI.h>namespace MyNativeModule {void install(jsi::Runtime &rt);
}// MyNativeModule.cpp
#include <react-native-cxx/JSI.h>
#include <iostream>namespace MyNativeModule {jsi::Function sayHello(jsi::Runtime &rt) {return jsi::Function::createFromHostFunction(rt,jsi::PropNameID::forAscii(rt, "sayHello"),1,[](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) {std::string name = args[0].asString(rt).utf8();std::cout << "Hello, " << name << std::endl;return jsi::Value::undefined();});}void install(jsi::Runtime &rt) {rt.global().setProperty(rt, jsi::PropNameID::forAscii(rt, "MyNativeModule"), jsi::Object(rt));rt.global().getProperty(rt, "MyNativeModule").asObject(rt).setProperty(rt, jsi::PropNameID::forAscii(rt, "sayHello"), sayHello(rt));}
}

在这个示例中,我们定义了一个名为 MyNativeModule 的 C++ 原生模块,它有一个名为 sayHello 的方法,接受一个字符串参数 name,并在控制台中打印出一条欢迎消息。

JavaScript

import { NativeModules } from 'react-native';const { MyNativeModule } = NativeModules;MyNativeModule.sayHello('John');

在这个示例中,我们首先导入了 NativeModules API。然后,我们使用 MyNativeModule 对象来调用 sayHello 方法,并传递一个字符串参数 name

高级:自定义 C++ 类型

在某些情况下,你可能需要在 C++ 原生模块中使用自定义的数据类型。RN 提供了一个名为 react-native-cxx 的库,用于简化这个过程。

以下是一个简单的示例,演示如何在 RN 应用程序中使用自定义的 C++ 类型:

C++

// MyNativeModule.h
#include <react-native-cxx/JSI.h>namespace MyNativeModule {class Person {public:std::string name;int age;Person(std::string name, int age) : name(name), age(age) {}};void install(jsi::Runtime &rt);
}// MyNativeModule.cpp
#include <react-native-cxx/JSI.h>
#include <iostream>namespace MyNativeModule {jsi::Function greet(jsi::Runtime &rt) {return jsi::Function::createFromHostFunction(rt,jsi::PropNameID::forAscii(rt, "greet"),1,[](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) {Person person = args[0].asObject(rt).asHostObject(rt).getHostObject(rt).as<Person>();std::cout << "Hello, " << person.name << " (" << person.age << ")" << std::endl;return jsi::Value::undefined();});}void install(jsi::Runtime &rt) {rt.global().setProperty(rt, jsi::PropNameID::forAscii(rt, "MyNativeModule"), jsi::Object(rt));rt.global().getProperty(rt, "MyNativeModule").asObject(rt).setProperty(rt, jsi::PropNameID::forAscii(rt, "greet"), greet(rt));}
}

在这个示例中,我们定义了一个名为 Person 的自定义 C++ 类型,并在 greet 方法中使用它。greet 方法接受一个 Person 对象作为参数,并在控制台中打印出一条问候消息。

JavaScript

import { NativeModules } from 'react-native';const { MyNativeModule } = NativeModules;const person = {name: 'John',age: 30,
};My

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何制作项目网页

一、背景 许多论文里经常会有这样一句话Supplementary material can be found at https://hri-eu.github.io/Lami/&#xff0c;这个就是将论文中的内容或者补充视频放到一个网页上&#xff0c;以更好的展示他们的工作。因此&#xff0c;这里介绍下如何使用前人提供的模板制作我…

Spring:Spring事务管理代码案例讲解

Spring事务管理知识讲解请见&#xff1a;Spring事务知识点讲解 下面演示一个代码示例进行理解。 需求 两个账户相互转账&#xff0c;并记录日志&#xff0c;即使有转账失败也要记录 需求分析 这里主要是需要开启事务机制来控制转入和转出&#xff1a; 1&#xff0c;创建一…

了解网络威胁情报:全面概述

网络威胁情报 CTI 是指系统地收集和分析与威胁相关的数据&#xff0c;以提供可操作的见解&#xff0c;从而增强组织的网络安全防御和决策过程。 在数字威胁不断演变的时代&#xff0c;了解网络威胁情报对于组织来说至关重要。复杂网络攻击的兴起凸显了制定强有力的策略以保护敏…

Scrapy图解工作流程-cnblog

1.1 介绍部分&#xff1a; 文字提到常用的Web框架有Django和Flask&#xff0c;接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分&#xff1a; Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…

【ArcGISPro】Sentinel-2数据处理

错误 默认拉进去只组织了4个波段,但是实际有12个波段 解决方案 数据下载 Sentinel-2 数据下载-CSDN博客 数据处理 数据查看 创建镶嵌数据集 在数据管理工具箱中找到创建镶嵌数据集

Python数据分析(OpenCV)

第一步通过pip安装依赖包&#xff0c;执行一下命令 pip install opencv-python 如果是Anaconda请在工具中自行下载 下载好咋们就可以在环境中使用了。 人脸识别的特征数据可以到 github上面下载&#xff0c;直接搜索OpenCV 然后我们在源码中通过cv2的级联分类器引入人脸的特征…

最小生成树-Prim与Kruskal算法

文章目录 什么是最小生成树&#xff1f;Prim算法求最小生成树Python实现&#xff1a; Kruskal算法求最小生成树并查集 Python实现&#xff1a; Reference 什么是最小生成树&#xff1f; 在图论中&#xff0c;树是图的一种&#xff0c;无法构成闭合回路的节点-边连接组合称之为…

深入理解 Java 基本语法之数组

目录 一、数组基础概念 二、数组的声明 1. 基本数据类型数组声明&#xff1a; 2. 引用数据类型数组声明&#xff1a; 三、数组的创建 四、数组的初始化 五、数组的使用 ​编辑1. 获取长度以及访问元素&#xff1a; 2. 数组作为方法的参数&#xff1a; 3. 数组作为方法…

计算机毕业设计PySpark+Scrapy农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

17. C++模板(template)1(泛型编程,函数模板,类模板)

⭐本篇重点&#xff1a;泛型编程&#xff0c;函数模板&#xff0c;类模板 ⭐本篇代码&#xff1a;c学习/07.函数模板 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. 泛型编程 二. 函数模板 2.1 函数模板的格式 2.2 函数模板的简单使用 2.3 函数模板…

Jupyter Notebook的安装和配置提示功能

Python开发环境搭建conda管理环境-CSDN博客 安装anaconda和对接到编译器的教程可以看上面这一篇 Jupyter Notebook是一种交互式计算环境&#xff0c;它允许用户在单个文档中编写和执行代码、方程、可视化和文本。与其他编译器相比&#xff0c;Jupyter Notebook的突出点在于其交…

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地&#xff08;只有第一次需要&#xff09; git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…

剑指Offer26.树的子结构

题目让判断B是不是A的子结构 但是我们进行判断是基于 两个树的根相等时, 去判断是否为子结构 针是否等于B的根节点的值对A做先序遍历的过程中 如果根节点相同我们去判断此时B是不是以该根节点的子树的子结构! 实际上进行先序遍历的同时要进行递归判断子结构 B是不是A节点的子结…

2024御网杯信息安全大赛个人赛wp(misc方向)

目录 一.信息安全大赛的通知二、编码转换1. 第一部分2. 第二部分3. 第三部分 三、1.txt四、buletooth 题目附件以及工具链接&#xff1a; 通过网盘分享的文件&#xff1a;御网杯附件 链接: https://pan.baidu.com/s/1LNA6Xz6eZodSV0Io9jGSZg 提取码: jay1 –来自百度网盘超级会…

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”&#xff1f;三、为什么有必要采用纵深安全防御策略&#xff1f;四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…

实战OpenCV之物体跟踪

基础入门 物体跟踪技术是一种计算机视觉领域的重要技术&#xff0c;用于连续地检测和定位视频序列中的一个或多个目标物体。物体跟踪技术在众多领域都有广泛的应用&#xff0c;比如&#xff1a;自动驾驶、安防监控、增强现实等。物体跟踪的基本流程包含以下几个主要步骤。 1、初…

Linux环境变量(添加环境变量、修改系统环境变量、内建命令和非内建命令)

Linux环境变量&#xff08;添加环境变量、修改系统环境变量、内建命令和非内建命令&#xff09; 1. 环境变量的介绍 环境变量&#xff08;environment variables&#xff09;一般是指在操作系统中用来指定操作系统运行环境的一些参数。环境变量是在操作系统中一个具有特定名字…

排序算法之插入排序篇

插入排序 思路&#xff1a; 就是将没有排序的元素逐步地插入到已经排好序的元素后面&#xff0c;保持元素的有序 视频的实现过程如下&#xff1a; 插入排序全过程 代码实现过程如下&#xff1a; public static void Insertion(int[] arr) { for (int i 1; i < arr.length…

AVL、B树和B+树

AVL树定义 AVL树&#xff08;Adelson-Velsky 和 Landis 树&#xff09;是一种自平衡的二叉搜索树&#xff08;Binary Search Tree, BST&#xff09;&#xff0c;由苏联数学家Georgy Adelson-Velsky和Evgenii Landis在1962年提出。AVL树通过在每个节点上维护一个平衡因子&#…

Unity ShaderLab 实现3D物体描边

实现思路&#xff1a; 给物体添加第二个材质球&#xff0c;在shader的顶点着色器中使顶点的位置变大&#xff0c;然后在片元着色器中输出描边颜色。 shader Graph实现如下&#xff1a; ShaderLab实现如下&#xff1a; Shader "Custom/Outline" {Properties{[HDR]_…