当前位置: 首页 > news >正文

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

相关文章:

React Native 原生开发指南

写在前面 React Native (RN) 是一个用于构建跨平台移动应用的框架。它允许开发者使用 JavaScript 和 React 来编写应用程序&#xff0c;并将其转换为原生代码。虽然 RN 提供了许多内置的组件和 API&#xff0c;但有时候你可能需要访问原生平台的特定功能或性能优化。为此&…...

【前端】JavaScript中的柯里化(Currying)详解及实现

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是柯里化&#xff1f;&#x1f4af;柯里化的特点&#x1f4af;柯里化的简单示例&#x1f4af;通用的柯里化实现&#x1f4af;柯里化让代码更易读的原因&#x1f4af…...

解决 docker 部署 vsftpd 速度慢问题

解决 docker 部署 vsftpd 速度慢问题 Docker 部署 ftp version: 3.8services:ftps:image: fauria/vsftpdcontainer_name: my-ftpsenvironment:- FTP_USERyourusername- FTP_PASSyourpassword- PASV_ADDRESS192.168.0.123 # 使用环境变量或直接指定IP地址- PASV_MIN_PORT4900…...

Java基础夯实——2.9 多线程如何共享数据

在 Java 多线程编程中&#xff0c;共享数据通过以下几种方式实现&#xff1a; 1. 使用共享对象 多个线程可以通过引用同一个对象来实现数据共享。例如&#xff1a; class SharedData {private int count;public synchronized void increment() {count;}public synchronized …...

【Leetcode Top 100】234. 回文链表

问题背景 给你一个单链表的头节点 h e a d head head&#xff0c;请你判断该链表是否为 回文链表&#xff08;回文 序列是向前和向后读都相同的序列&#xff09;。如果是&#xff0c;返回 t r u e true true&#xff1b;否则&#xff0c;返回 f a l s e false false。 数据…...

GitLab指定用户分配合并权限

进入项目 -》 Project Settings Repository -》展开 Protected branches -》 添加要保护的分支&#xff0c;设置角色 管理用户角色权限 查看到不同用户的角色&#xff0c;一般设置Developer只有Merger Request权限&#xff0c;Maintainer还有Merge审批权限 GitLab 中的权限…...

五,[GXYCTF2019]Ping Ping Ping1

进入靶场&#xff0c;有提示 我们在url试着输入本地IP&#xff0c;返回了ping命令 既然要在url处传参&#xff0c;那就用postman&#xff0c;再输入ip127.0.0.1 & ls&#xff0c;试着列出目录内容 ok&#xff0c;好像是个脏话,它过滤了空格 试着穿越又看到了脏话&#xff0…...

基于STM32的智能无人机自主飞行与目标识别系统设计

目录 引言系统需求分析 2.1 功能需求 2.2 硬件需求 2.3 软件需求系统设计 3.1 总体架构 3.2 各模块设计系统实现 4.1 硬件实现 4.2 软件实现系统调试与优化总结与展望 1. 引言 随着无人机技术的快速发展&#xff0c;无人机在军事侦察、环境监测、物流配送等领域的应用逐渐增多…...

C 语言数组与函数:核心要点深度剖析与高效编程秘籍

我的个人主页 我的专栏&#xff1a;C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 引言数组基础 2.1 数组的定义与初始化 2.2 一维数组的基本操作 2.3 二维数组及其应用 2.4 数组与指针的关系函数基础 3.1 函数的定义与调用 3.2…...

汽车轮毂结构分析有哪些?国产3D仿真分析实现静力学+模态分析

本文为CAD芯智库原创&#xff0c;未经允许请勿复制、转载&#xff01; 之前分享了如何通过国产三维CAD软件如何实现「汽车/汽配行业产品设计」&#xff0c;兼容NX&#xff08;UG&#xff09;、Creo&#xff08;Proe&#xff09;&#xff0c;轻松降低企业上下游图纸交互成本等。…...

解决jupyter notebook 新建或打开.ipynb 报500 : Internal Server Error(涉及jinja2兼容性问题)

报错&#xff1a; [E 10:09:52.362 NotebookApp] 500 GET /notebooks/Untitled16.ipynb?kernel_namepyt hon3 (::1) 93.000000ms refererhttp://localhost:8888/tree ...... 重点是&#xff1a; from .exporters import * File "C:\ProgramData\Anaconda3\lib\site-p…...

【若依ruoyi Vue前端线上个人服务器部署】以及常见报错问题解决

提示&#xff1a;【若依ruoyi Vue前端线上个人服务器部署】以及常见报错问题解决 文章目录 前言一、若依ruoyi Vue前端部署常见两种错误1、404问题2、找不到….模块 二、使用步骤&#xff08;正式开始&#xff09;1.修改vue.config.js中的publicPath属性。2.修改router/index.j…...

Python学习第十天--处理CSV文件和JSON数据

CSV&#xff1a;简化的电子表格&#xff0c;被保存为纯文本文件 JSON&#xff1a;是一种数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;以JavaScript源代码的形式将信息保存在纯文本文件中 一、csv模块 CSV文件中的每行代表电…...

python基础(一)

python语言特点 解释型语言代码执行过程中通过解释器将代码转换为机器语言&#xff0c;并立即执行&#xff1b;编译型语言执行前需要经过编译整个代码文件为机器语言的可执行文件&#xff0c;然后执行能找出大部分错误错误处理解释型语言在运行时发现错误&#xff0c;编译型语…...

go-carbon v2.5.0 发布,轻量级、语义化、对开发者友好的 golang 时间处理库

carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库&#xff0c;提供了对时间穿越、时间差值、时间极值、时间判断、星座、星座、农历、儒略日 / 简化儒略日、波斯历 / 伊朗历的支持。 carbon 目前已捐赠给 dromara 开源组织&#xff0c;已被 awesome-go 收录&am…...

守护进程

目录 守护进程 前台进程 后台进程 session&#xff08;进程会话&#xff09; 前台任务和后台任务比较好 本质 绘画和终端都关掉了&#xff0c;那些任务仍然在 bash也退了&#xff0c;然后就托孤了 ​编辑 守护进程化---不想受到任何用户登陆和注销的影响​编辑 如何…...

学习日记_20241126_聚类方法(自组织映射Self-Organizing Maps, SOM)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…...

【接口自动化测试】一文从0到1详解接口测试协议!

接口自动化测试是软件开发过程中重要的环节之一。通过对接口进行测试&#xff0c;可以验证接口的功能和性能&#xff0c;确保系统正常运行。本文将从零开始详细介绍接口测试的协议和规范。 定义接口测试协议 接口测试协议是指用于描述接口测试的规范和约定。它包含了接口的请求…...

安全设备-日志审计-系统安装部署配置

3.1 系统安装部署概述 通过系统初始化安装部署&#xff0c;可实现对系统的基础管理工作。系统安装基本部署涉及功能有时间配置、 资产组、资产、用户组、用户、时间配置等&#xff09; 3.2 系统安装部署配置举例 3.2.1 用户场景 本阶段进行系统安装&#xff0c;进行相关设…...

【ArcGIS Pro】实现一下完美的坐标点标注

在CAD里利用湘源可以很快点出一个完美的坐标点标注。 但是在ArcGIS Pro中要实现这个效果却并不容易。 虽然有点标题党&#xff0c;这里就尽量在ArcGIS Pro中实现一下。 01 标注实现方法 首先是准备工作&#xff0c;准备一个点要素图层&#xff0c;包含xy坐标字段。 在地图框…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...