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

【大前端】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.dtcms.com/a/354746.html

相关文章:

  • 基于FPGA的情绪感知系统设计方案:心理健康监测应用(五)
  • Ckman部署clickhouse
  • Qt基础_xiaozuo
  • Groovy集合常用简洁语法
  • linux mysql 数据库启动异常问题记录
  • KafKa学习笔记
  • AT_abc407_e [ABC407E] Most Valuable Parentheses
  • 前端开发中的CSS变量管理:实现缓存与响应式更新
  • 从 WPF 到 Avalonia 的迁移系列实战篇3:ResourceDictionary资源与样式的差异与迁移技巧
  • CuTe C++ 简介01,从示例开始
  • wpf之ListBox
  • 一个客户端直接掉线或断点,服务器怎么快速识别
  • 通过代码认识 CNN:用 PyTorch 实现卷积神经网络识别手写数字
  • audioMAE模型代码分析
  • 循环神经网络——pytorch实现循环神经网络(RNN、GRU、LSTM)
  • 深度学习——卷积神经网络(PyTorch 实现 MNIST 手写数字识别案例)
  • SpringBoot项目使用Liquibase 数据库版本管理
  • Day16_【机器学习—KNN算法】
  • IDA Pro 逆向分析快捷键大全及核心用法详解
  • 【Day 35】Linux-Mysql错误总结
  • 微信小程序对接EdgeX Foundry详细指南
  • 导入文件允许合并表格
  • 上海控安:汽车API安全-风险与防护策略解析
  • Elasticsearch数据迁移方案深度对比:三种方法的优劣分析
  • 领悟8种常见的设计模式
  • 74HC595芯片简析
  • OpenCV 基础操作实战指南:从图像处理到交互控制
  • Ubuntu有限网口无法使用解决方法
  • 企业级AI应用场景的核心特征
  • Fluent Bit针对kafka心跳重连机制详解(上)