【大前端】React Native 调用 Android、iOS 原生能力封装


📖 React Native 调用 Android、iOS 原生能力封装

1. 原理

React Native 的 核心思想

  • JS 层(React 代码)不能直接调用 Android/iOS 的 API。

  • RN 提供了 Native Module 机制

    • Android:Java/Kotlin → 继承 ReactContextBaseJavaModule,通过 @ReactMethod 暴露方法。
    • iOS:Objective-C/Swift → 使用 RCT_EXPORT_MODULERCT_EXPORT_METHOD 暴露方法。
  • JS 调用时通过 NativeModules 拿到对应的模块,再调用方法。

  • 双向通信

    • JS → 原生(方法调用)
    • 原生 → JS(事件通知 / 回调 Promise)

2. Android 封装原生能力

(1)新建原生 Module

// MyNativeModule.java
package com.myapp;import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;public class MyNativeModule extends ReactContextBaseJavaModule {MyNativeModule(ReactApplicationContext context) {super(context);}@Overridepublic String getName() {return "MyNative"; // JS 调用时用的名字}// 示例:获取电池电量@ReactMethodpublic void getBatteryLevel(Promise promise) {try {int battery = 80; // 假设写死,实际可用系统 API 获取promise.resolve(battery);} catch (Exception e) {promise.reject("ERROR", e);}}
}

(2)注册 Module

// MyPackage.java
package com.myapp;import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class MyPackage implements ReactPackage {@Overridepublic List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {List<NativeModule> modules = new ArrayList<>();modules.add(new MyNativeModule(reactContext));return modules;}@Overridepublic List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {return Collections.emptyList();}
}

MainApplication.java 里注册:

packages.add(new MyPackage());

3. iOS 封装原生能力

(1)Objective-C 示例

// MyNativeModule.m
#import <React/RCTBridgeModule.h>@interface RCT_EXTERN_MODULE(MyNative, NSObject)RCT_EXTERN_METHOD(getBatteryLevel:(RCTPromiseResolveBlock)resolverejecter:(RCTPromiseRejectBlock)reject)@end

(2)Swift 示例

@objc(MyNative)
class MyNative: NSObject {@objcfunc getBatteryLevel(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {let battery = 80 // 假设写死resolve(battery)}
}

4. JS 调用

import { NativeModules } from 'react-native';
const { MyNative } = NativeModules;async function checkBattery() {try {const level = await MyNative.getBatteryLevel();console.log("电池电量:", level);} catch (e) {console.error(e);}
}

5. 原生 → JS 的事件通知

有些能力(如推送、传感器数据)需要原生主动回调 JS。

  • Android:使用 DeviceEventManagerModule
WritableMap params = Arguments.createMap();
params.putString("event", "BatteryLow");
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("BatteryEvent", params);
  • iOS:使用 RCTEventEmitter
[self sendEventWithName:@"BatteryEvent" body:@{@"event": @"BatteryLow"}];
  • JS 监听
import { NativeEventEmitter, NativeModules } from 'react-native';const eventEmitter = new NativeEventEmitter(NativeModules.MyNative);
eventEmitter.addListener('BatteryEvent', (event) => {console.log(event);
});

6. 最佳实践

  1. 模块化封装

    • 每个功能一个 Native Module,按业务拆分。
    • 统一放在 /native-modules/ 目录下,JS 层再封装一层 API。
  2. 跨平台统一接口

    • 在 JS 层写一个 Battery.ts,内部判断 Platform.OS 调用 Android/iOS 实现。
  3. 避免直接调用 NativeModules

    • 封装成业务方法,例如:

      export async function getBatteryLevel(): Promise<number> {return await NativeModules.MyNative.getBatteryLevel();
      }
      
  4. 新架构 TurboModules(进阶):

    • 使用 JSI 直接绑定 C++ → JS 方法,无需 Bridge。
    • 更高性能(避免 JSON 序列化)。

📌 总结:
RN 调用原生能力 = JS ↔ Native Module ↔ Android/iOS API

  • JS 调用 Native:NativeModules.MyNative.xxx()
  • Native 调用 JS:事件/回调/Promise
  • 封装要点:统一接口、模块化、尽量隐藏平台差异

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

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

相关文章

HOOK安卓木马重大升级,勒索功能扩展至107项

勒索覆盖屏成新特征网络安全研究人员发现名为HOOK的安卓银行木马新变种&#xff0c;该恶意软件新增勒索软件式覆盖屏功能用于显示勒索信息。Zimperium zLabs研究员Vishnu Pratapagiri表示&#xff1a;"最新变种的显著特征是能够部署全屏勒索覆盖界面&#xff0c;旨在胁迫受…

GeoScene Maps 完整入门指南:从安装到实战

什么是GeoScene MapsGeoScene Maps是一套功能强大的Web地图开发平台&#xff0c;它基于现代Web技术构建&#xff0c;为开发者提供了丰富的地图服务和开发工具。与其他地图API相比&#xff0c;GeoScene Maps具有以下特点&#xff1a;核心优势全面的地图服务&#xff1a;支持2D/3…

本地大模型部署:Ollama 部署与 Python 接口调用全攻略

本地大语言模型实践&#xff1a;Ollama 部署与 Python 接口调用全攻略 一、引言 过去我们使用大语言模型&#xff08;LLM&#xff09;&#xff0c;更多依赖于 OpenAI API、Claude API 等云端服务。它们虽然强大&#xff0c;但存在两大问题&#xff1a; 隐私与数据安全&#xff…

OpenFeign:让微服务间调用像本地方法一样简单

引言&#xff1a;微服务通信的演进之路什么是OpenFeign&#xff1f;核心特性概览快速开始&#xff1a;搭建OpenFeign环境环境准备与依赖配置启用OpenFeign功能基础用法&#xff1a;从简单示例开始定义第一个Feign客户端在服务中调用Feign客户端进阶配置&#xff1a;深度定制Ope…

openharmony之一多开发:产品形态配置讲解

OpenHarmony 的“一多开发”指的是 一次开发&#xff0c;多端部署&#xff08;简称“一多”&#xff09;&#xff0c;即使用 一套代码工程&#xff0c;一次开发上架&#xff0c;按需部署到不同终端设备上 &#x1f3af; 核心概念速览 产品形态定义 写在前面&#xff1a;1.不同的…

被迫在linux上用R(真的很难用啊)之如何在linux上正常使用R

总有一些情况&#xff0c;让你不得不在linux上使用R。。。 在我不断试错&#xff0c;不断尝试过程中&#xff08;恩&#xff0c;新手疯狂踩坑&#xff09; 发现最简单的办法是&#xff1a; 1 mamba创建一个新环境&#xff0c;在新环境中使用R 2 转变思维&#xff0c;都在linux上…

【STM32】G030单片机的独立看门狗

目录 一、简单介绍 二、特性 三、窗口选项 四、cubeMX配置 不使用窗口功能 使用窗口功能 五、工程链接 一、简单介绍 独立看门狗&#xff0c;顾名思义&#xff0c;是不依靠系统而独立存在的看门狗 可以脱离应用运行&#xff0c;但缺陷在于时序精度比窗口看门狗低 主要…

VR党建工作站-红色教育基地

近几年在市场爆火的VR党建工作站提升了传统的党建方式&#xff0c;利用VR/AR技术&#xff0c;为广大党员提供沉浸式、多维度的党建学习。佩京利用VR技术搭建的教育场景&#xff0c;可以更加直观地了解党的发展历程&#xff0c;提高学习效果&#xff0c;激发奋斗精神。VR党建工作…

配置 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 数据库、Camo 代理服务

配置 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 数据库、Camo 代理服务 本文章首发于&#xff1a;连接 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 数据库、Camo 代理服务 - Ayaka 的小站 为确保更好阅读格式和阅读体验&#xff0c;更建议前往个人博客…

2025年渗透测试面试题总结-36(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、计算机网络基础 1. HTTP 状态码&#xff08;502/503/501&#xff09; 2. HTTP 请求方式及作用 3. 计…

QT5.15.2 - 安装时如果下载不了停了,需要加速

文章目录QT5.15.2 - 安装时如果下载不了停了&#xff0c;需要加速概述笔记安装的选项可用的国内镜像站点也有很多ENDQT5.15.2 - 安装时如果下载不了停了&#xff0c;需要加速 概述 在 https://download.qt.io/archive/online_installers 中找在线安装包。 用qt-online-instal…

着色器语言

以下是主流的几种着色器语言&#xff1a;1. HLSL (High-Level Shading Language)这是你在Unity中最主要、最应该学习的语言。开发方&#xff1a;微软 (Microsoft)主要应用平台&#xff1a;Unity、DirectX (Windows, Xbox)特点&#xff1a;语法与C语言非常相似&#xff0c;易于学…

VILA运行全程踩坑笔记

VILA运行全程踩坑笔记1. docker的尝试2. 本地部署服务端仓库地址&#xff1a;https://github.com/NVlabs/VILA 全文按照一路踩坑的时间顺序记录&#xff0c;不建议按照步骤一步一步来重复每一个踩坑的悲伤故事&#xff0c;不如先全部看完&#xff0c;再实际上手操作。 省流&am…

Python爬虫: 分布式爬虫架构讲解及实现

了解Python分布式爬虫框架及其实现,能让你在处理大规模数据采集时事半功倍。本文我会结合自己的知识,从核心原理、主流框架、关键技术到实践建议,为你提供一个详细的解读。 🧠 一、分布式爬虫核心原理 分布式爬虫的核心思想是将爬取任务分解,由多个爬虫节点(Worker)协…

君正T31学习(四)- MT7682+VLC出图

一、简介 前几篇文章介绍了如何通过SD卡来播放sensor录制的视频&#xff0c;但是效率很低&#xff0c;所以需要一种效率更高的方法&#xff0c;就是本篇的主角MT7682VLC。 Mt7682在系统中注册为一个以太网卡驱动&#xff0c;接口名为eth0&#xff0c;可以使用Linux通用的socket…

【办公自动化】如何使用Python库高效自动化处理图像?

在日常办公中&#xff0c;我们经常需要处理大量图像&#xff0c;如产品照片、营销素材、文档扫描件等。手动处理这些图像不仅耗时&#xff0c;还容易出错。通过Python自动化图像处理&#xff0c;我们可以高效地完成批量缩放、裁剪、加水印、格式转换等任务&#xff0c;大大提高…

Beats与Elasticsearch高效数据采集指南

Beats 是 Elastic Stack 中的数据采集器&#xff0c;用于从各种来源&#xff08;日志、指标、网络数据等&#xff09;轻量级收集数据&#xff0c;而 Elasticsearch 是搜索和分析引擎&#xff0c;负责存储、索引和快速检索数据。二者结合可搭建强大的数据分析管道&#xff08;如…

前端异常监控,性能监控,埋点,怎么做的

你想做的是一个 前端监控系统&#xff08;Frontend Monitoring / RUM, Real User Monitoring&#xff09;&#xff0c;主要包括&#xff1a;异常监控&#xff08;JS 报错、资源加载错误、Promise 未捕获异常&#xff09;性能监控&#xff08;白屏时间、首屏时间、页面加载时间、…

Kubernetes一EFK日志架构

前言&#xff1a;​ 在云原生时代&#xff0c;Kubernetes已成为容器编排的事实标准&#xff0c;它赋予了应用极高的弹性、可移植性和密度。然而&#xff0c;这种动态、瞬时的特性也带来了可观测性的新难题&#xff1a;当数以百计的Pod在节点间频繁创建和销毁时&#xff0c;传统…

Linux下的软件编程——网络编程(tcp)

重点&#xff1a;1.UDP和TCP区别2.TCP三次握手和四次挥手3.TCP粘包问题及解决办法4.TCP客户端和服务端的编程流程 TCP&#xff1a;传输层传输控制协议&#xff08;流式套接字&#xff09;1&#xff09;TCP的特点1.面向数据流2.有连接&#xff08;通信之前必须建立连接…