原生模块助手Skill native-module-helper

这个技能用于创建React Native应用中的原生模块,帮助开发者桥接JavaScript和原生代码(iOS和Android),实现集成原生SDK、优化性能关键代码或访问平台特定API。关键词包括React Native、原生模块、桥接、iOS、Android、Turbo Module、移动开发、前端开发、性能优化、跨平台开发。

移动开发 0 次安装 0 次浏览 更新于 3/9/2026

name: native-module-helper description: 为iOS和Android创建自定义React Native原生模块。当集成原生SDK、优化性能关键代码或访问平台特定API时使用。触发词包括"原生模块"、“桥接”、“原生代码”、“iOS桥接”、“Android桥接”、“Turbo Module”。

Native Module Helper

构建自定义原生模块,以在React Native中桥接JavaScript和原生代码。

快速开始

原生模块将原生功能暴露给JavaScript。根据React Native版本选择:

  • 旧版桥接: RN < 0.68(稳定,广泛支持)
  • Turbo模块: RN >= 0.68(性能更好,类型安全)

说明

步骤1:规划模块接口

设计JavaScript API:

// 你想从JS中调用的
import { NativeModules } from 'react-native';
const { MyModule } = NativeModules;

// 同步
const result = MyModule.getValue();

// 异步(Promise)
const data = await MyModule.fetchData();

// 使用回调
MyModule.processData(input, (error, result) => {
  if (error) console.error(error);
  else console.log(result);
});

// 事件发射器
MyModule.addListener('onUpdate', (event) => {
  console.log(event);
});

保持桥接调用最小化:

  • 尽可能批量操作
  • 避免频繁的小调用
  • 使用事件进行连续更新

步骤2:创建模块结构

文件结构:

MyModule/
├── ios/
│   ├── MyModule.h
│   ├── MyModule.m(或.swift)
│   └── MyModule-Bridging-Header.h(如果使用Swift)
├── android/
│   └── src/main/java/com/mymodule/
│       ├── MyModulePackage.java
│       └── MyModule.java(或.kt)
├── js/
│   └── NativeMyModule.ts
└── package.json

步骤3:实现iOS模块

Objective-C(.h文件):

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface MyModule : RCTEventEmitter <RCTBridgeModule>
@end

Objective-C(.m文件):

#import "MyModule.h"

@implementation MyModule

RCT_EXPORT_MODULE();

// 同步方法
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getValue)
{
  return @"value";
}

// 异步使用Promise
RCT_EXPORT_METHOD(fetchData:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
  // 执行操作
  if (success) {
    resolve(@{@"data": result});
  } else {
    reject(@"ERROR_CODE", @"错误消息", error);
  }
}

// 异步使用回调
RCT_EXPORT_METHOD(processData:(NSString *)input
                  callback:(RCTResponseSenderBlock)callback)
{
  // 处理数据
  callback(@[[NSNull null], result]); // [错误, 结果]
}

// 事件发射器
- (NSArray<NSString *> *)supportedEvents
{
  return @[@"onUpdate"];
}

- (void)sendUpdate:(NSDictionary *)data
{
  [self sendEventWithName:@"onUpdate" body:data];
}

@end

步骤4:实现Android模块

Java模块:

package com.mymodule;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.modules.core.DeviceEventManagerModule;

public class MyModule extends ReactContextBaseJavaModule {
    private ReactApplicationContext reactContext;

    public MyModule(ReactApplicationContext context) {
        super(context);
        this.reactContext = context;
    }

    @Override
    public String getName() {
        return "MyModule";
    }

    // 同步方法
    @ReactMethod(isBlockingSynchronousMethod = true)
    public String getValue() {
        return "value";
    }

    // 异步使用Promise
    @ReactMethod
    public void fetchData(Promise promise) {
        try {
            WritableMap result = Arguments.createMap();
            result.putString("data", "value");
            promise.resolve(result);
        } catch (Exception e) {
            promise.reject("ERROR_CODE", "错误消息", e);
        }
    }

    // 异步使用回调
    @ReactMethod
    public void processData(String input, Callback callback) {
        try {
            String result = process(input);
            callback.invoke(null, result); // 错误, 结果
        } catch (Exception e) {
            callback.invoke(e.getMessage(), null);
        }
    }

    // 事件发射器
    private void sendEvent(String eventName, WritableMap params) {
        reactContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit(eventName, params);
    }
}

包注册:

package com.mymodule;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyModulePackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new MyModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

步骤5:链接模块

自动链接(RN >= 0.60):

在模块根目录创建package.json

{
  "name": "react-native-my-module",
  "version": "1.0.0",
  "main": "js/index.js",
  "react-native": "js/index.js"
}

手动链接(如果需要):

iOS:添加到Podfile

pod 'MyModule', :path => '../node_modules/react-native-my-module'

Android:添加到settings.gradle

include ':react-native-my-module'
project(':react-native-my-module').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-my-module/android')

步骤6:创建TypeScript接口

// js/NativeMyModule.ts
import { NativeModules, NativeEventEmitter } from 'react-native';

interface MyModuleInterface {
  getValue(): string;
  fetchData(): Promise<{ data: string }>;
  processData(input: string, callback: (error: string | null, result: string | null) => void): void;
  addListener(eventName: string, listener: (event: any) => void): void;
  removeListeners(count: number): void;
}

const { MyModule } = NativeModules;
const eventEmitter = new NativeEventEmitter(MyModule);

export default MyModule as MyModuleInterface;
export { eventEmitter };

常见模式

线程处理

iOS(在后台线程上运行):

RCT_EXPORT_METHOD(heavyTask:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 繁重操作
    NSString *result = [self performHeavyOperation];
    
    dispatch_async(dispatch_get_main_queue(), ^{
      resolve(result);
    });
  });
}

Android(在后台线程上运行):

@ReactMethod
public void heavyTask(Promise promise) {
    new Thread(() -> {
        try {
            String result = performHeavyOperation();
            promise.resolve(result);
        } catch (Exception e) {
            promise.reject("ERROR", e);
        }
    }).start();
}

数据类型转换

iOS:

// JS -> 原生
NSString *string = [RCTConvert NSString:value];
NSNumber *number = [RCTConvert NSNumber:value];
NSArray *array = [RCTConvert NSArray:value];
NSDictionary *dict = [RCTConvert NSDictionary:value];

// 原生 -> JS
return @{
  @"string": @"value",
  @"number": @(42),
  @"array": @[@"a", @"b"],
  @"dict": @{@"key": @"value"}
};

Android:

// JS -> 原生(自动)
String string = input;
int number = input;
ReadableArray array = input;
ReadableMap map = input;

// 原生 -> JS
WritableMap result = Arguments.createMap();
result.putString("string", "value");
result.putInt("number", 42);

WritableArray array = Arguments.createArray();
array.pushString("a");
array.pushString("b");
result.putArray("array", array);

错误处理

iOS:

RCT_EXPORT_METHOD(riskyOperation:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
  NSError *error = nil;
  id result = [self performOperation:&error];
  
  if (error) {
    reject(@"OPERATION_FAILED", error.localizedDescription, error);
  } else {
    resolve(result);
  }
}

Android:

@ReactMethod
public void riskyOperation(Promise promise) {
    try {
        Object result = performOperation();
        promise.resolve(result);
    } catch (Exception e) {
        promise.reject("OPERATION_FAILED", e.getMessage(), e);
    }
}

高级

详细平台特定指南:

故障排除

找不到模块:

  • 验证package.json配置
  • 运行pod install(iOS)或重新构建(Android)
  • 检查原生代码中的模块名称是否匹配

方法不可用:

  • 确保使用RCT_EXPORT_METHOD
  • 检查方法签名是否匹配
  • 重新构建原生代码

调用方法时崩溃:

  • 检查线程安全性
  • 验证数据类型转换
  • 添加空值检查
  • 检查错误处理

未接收到事件:

  • 验证supportedEvents(iOS)
  • 检查事件发射器设置
  • 确保在事件触发前添加监听器

最佳实践

  1. 最小化桥接调用:批量操作,使用事件进行更新
  2. 类型安全:使用TypeScript接口
  3. 错误处理:始终优雅地处理错误
  4. 线程处理:将繁重操作移出主线程
  5. 内存管理:清理资源,移除监听器
  6. 测试:在iOS和Android上测试
  7. 文档:清晰记录API
  8. 版本控制:使用语义化版本控制