在 React Native (RN) 中,JavaScript 可以通过与原生代码(Android 或 iOS)进行交互来调用原生模块。React Native 提供了一个 NativeModules
API,用于从 JavaScript 代码中访问原生模块。你可以通过自定义原生模块将 Java/Kotlin 或 Objective-C/Swift 代码暴露给 JavaScript 层,或者使用 React Native 自带的一些原生模块。
1. 使用现有的原生模块
React Native 本身提供了一些原生模块,可以直接通过 JavaScript 调用这些模块,例如:
- Geolocation:获取设备位置
- CameraRoll:访问设备图库
- PushNotification:发送推送通知
- ToastAndroid:在 Android 上显示原生 Toast 消息
示例:调用现有原生模块(例如 ToastAndroid
)
import { ToastAndroid } from 'react-native';
// 显示一个 Toast 消息
ToastAndroid.show('Hello from React Native!', ToastAndroid.SHORT);
2. 自定义原生模块
如果需要调用自定义的原生代码,可以创建一个自定义的原生模块。你需要在 Android 和 iOS 中分别编写相应的原生代码,并通过 NativeModules
API 进行调用。
步骤:
- 在 Android 中创建原生模块(使用 Java/Kotlin)
在 Android 端创建一个原生模块,并暴露给 JavaScript 使用。
- 创建原生模块(例如
MyCustomModule.java
):
package com.yourapp;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class MyCustomModule extends ReactContextBaseJavaModule {
public MyCustomModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "MyCustomModule"; // 这个名字会用于 JavaScript 端调用
}
@ReactMethod
public void showMessage(String message) {
// 在 Android 端显示一个 Toast
android.widget.Toast.makeText(getReactApplicationContext(), message, android.widget.Toast.LENGTH_SHORT).show();
}
}
- 将模块注册到 React Native 中(在
MainApplication.java
中):
import com.yourapp.MyCustomModule; // 导入你的模块
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new MyCustomPackage() // 添加你的模块
);
}
- 在 iOS 中创建原生模块(使用 Objective-C/Swift)
- 创建原生模块(例如
MyCustomModule.m
):
#import <React/RCTBridgeModule.h>
@interface MyCustomModule : NSObject <RCTBridgeModule>
@end
@implementation MyCustomModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(showMessage:(NSString *)message)
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Message"
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootViewController presentViewController:alert animated:YES completion:nil];
}
@end
- 将模块注册到 React Native 中(在
AppDelegate.m
中):
#import "MyCustomModule.h" // 导入你的模块
// 在 `didFinishLaunchingWithOptions` 方法中注册模块
[RCTBridgeModule registerModule:[MyCustomModule class]];
- 通过 JavaScript 调用原生模块:
在 JavaScript 代码中使用 NativeModules
来访问你创建的原生模块。
import { NativeModules } from 'react-native';
const { MyCustomModule } = NativeModules;
// 调用原生方法
MyCustomModule.showMessage('Hello from JavaScript!');
3. 传递数据和回调
在原生模块中,除了简单的方法调用,还可以传递数据或使用回调来异步处理数据。
传递参数和使用回调:
Android(Java):
@ReactMethod
public void showMessage(String message, Callback successCallback) {
// 显示消息
android.widget.Toast.makeText(getReactApplicationContext(), message, android.widget.Toast.LENGTH_SHORT).show();
// 调用回调
successCallback.invoke("Message displayed successfully");
}
iOS (Objective-C):
RCT_EXPORT_METHOD(showMessage:(NSString *)message callback:(RCTResponseSenderBlock)callback)
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Message"
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootViewController presentViewController:alert animated:YES completion:nil];
// 调用回调
callback(@[@"Message displayed successfully"]);
}
JavaScript:
MyCustomModule.showMessage('Hello from JavaScript!', (message) => {
console.log(message); // "Message displayed successfully"
});
总结
- 调用现有原生模块:通过 React Native 自带的 API(如
ToastAndroid
,Geolocation
等)直接访问。 - 创建自定义原生模块:在 Android 和 iOS 端分别编写原生代码,并通过
NativeModules
在 JavaScript 中进行调用。