React Native 原生开发指南

embedded/2024/11/30 13:10:46/

写在前面

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

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

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

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

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

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

http://www.ppmy.cn/embedded/141754.html

相关文章

毕昇入门学习

schemas.py 概述 这段代码主要定义了一系列基于 Pydantic 的数据模型&#xff08;BaseModel&#xff09;&#xff0c;用于数据验证和序列化&#xff0c;通常用于构建 API&#xff08;如使用 FastAPI&#xff09;。这些模型涵盖了用户认证、聊天消息、知识库管理、模型配置等多…

滑动窗口篇——如行云流水般的高效解法与智能之道(3)

前言&#xff1a; 上篇我们介绍了滑动窗口的进阶练习&#xff0c;本篇难度继续升级&#xff0c;同样结合具体题目&#xff0c;帮助大家进一步掌握和运用滑动窗口。 一. 找到字符串中所有字母异位词 题目链接&#xff1a;438. 找到字符串中所有字母异位词 - 力扣&#xff08;L…

如何写一份优质技术文档

作者简介&#xff1a; 本文作者拥有区块链创新专利30&#xff0c;是元宇宙标准化工作组成员、香港web3标准工作组成员&#xff0c;参与编写《数据资产确权与交易安全评价标准》、《链接元宇宙&#xff1a;应用与实践》、《香港Web3.0标准化白皮书》等标准&#xff0c;下面提供…

C语言解决空瓶换水问题:高效算法与实现

标题&#xff1a;C语言解决空瓶换水问题&#xff1a;高效算法与实现 一、问题描述 在一个饮料促销活动中&#xff0c;你可以通过空瓶换水的方式免费获得更多的水&#xff1a;3个空瓶可以换1瓶水。喝完这瓶水后&#xff0c;空瓶会再次变为空瓶。假设你最初拥有一定数量的空瓶&a…

线程的run()和start()有什么区别?

线程的run()方法和start()方法在Java多线程编程中具有显著的区别。以下是关于这两个方法区别的详细解释&#xff1a; run()方法 定义&#xff1a; run()方法是Thread类中的一个普通方法&#xff0c;用于定义线程的主体逻辑&#xff0c;即线程需要执行的任务。执行方式&#x…

龙迅#LT6912适用于HDMI2.0转HDMI+LVDS/MIPI,分辨率高达4K60HZ,支持音频和HDCP2.2

1. 描述 LT6912是一款高性能的HDMI2.0转HDMI和LVDS和MIPI转换器。 HDMI2.0 输入和输出均支持高达 6Gbps 的数据速率&#xff0c;为4k60Hz视频提供足够的带宽。此外&#xff0c;还支持 HDCP2.2 进行数据解密&#xff08;无数据 加密&#xff09;。 对于 LVDS 输出&#xff0c…

Oracle12.2 RAC集群管理之增加删除节点(DNS解析)

Oracle12.2 RAC集群管理之增加删除节点 该章节实验是基于此章节基础上操作&#xff1a; Oracle LinuxR7安装Oracle 12.2 RAC集群实施&#xff08;DNS解析&#xff09;-CSDN博客 操作系统参数配置 172.30.21.101 hefei1 hefei1.hefeidb.com 172.30.21.102 hefei2 hef…

户外单兵拍摄神器——机器人云台

机器人选型 在户外拍摄移动镜头时&#xff0c;确保运镜的稳定性是一个复杂的任务。首先&#xff0c;需要使用高质量的稳定器或云台&#xff0c;以减少手持设备时的抖动。户外地形多变&#xff0c;如山坡或不平坦的地面&#xff0c;给摄影师的移动带来挑战&#xff0c;这要…