React Native 作为跨平台开发框架,在移动开发中使用越来越普及,同时还有着众多的社区支持。除了内置的组件和 API,开发者还可以通过封装 Native 模块,利用 Native 的强大功能来扩展 React Native 的使用能力。本文将介绍如何封装 Native 模块,并提供详细的示例代码。
Native 模块介绍
在 React Native 中,我们通常使用 JavaScript 编写应用程序的逻辑,然后使用 Bridge 将其发送到 Native 代码中去执行,最终显示在屏幕上。而 Native 模块则是一种 Java 或 Objective-C 类或模块,通过 Bridge 向 JavaScript 暴露方法,使得 JavaScript 可以调用 Native 代码来执行相关操作。
封装 Native 模块
假设我们现在需要一个 Native 模块来获取设备信息,我们可以按如下步骤进行封装。
Android 封装步骤
- 创建一个 Java 类来定义 Native 模块:
// www.javascriptcn.com code example
public class DeviceInfoModule extends ReactContextBaseJavaModule {
private static final String TAG = "DeviceInfoModule";
private static final String NAME = "DeviceInfo";
public DeviceInfoModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return NAME;
}
@ReactMethod
public void getDeviceInfo(Promise promise) {
try {
WritableMap map = Arguments.createMap();
map.putString("brand", Build.BRAND);
map.putString("model", Build.MODEL);
map.putString("os", Build.VERSION.RELEASE);
promise.resolve(map);
} catch (Exception e) {
promise.reject(e);
}
}
}这是一个简单的 Java 类,它继承了 ReactContextBaseJavaModule 类,并且实现了 getName() 和 @ReactMethod 注解。其中,getName() 方法用于定义该模块的名称,@ReactMethod 注解表示该方法暴露给 JavaScript 端调用。
- 创建一个 ReactPackage 类来注册 Native 模块:
// www.javascriptcn.com code example
public class DeviceInfoPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new DeviceInfoModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}这个类实现了 ReactPackage 类,并且覆盖了其中的 createNativeModules() 方法。在这个方法里,我们可以添加上面创建的 Native 模块。
- 在
MainApplication.java中注册刚刚创建的 Package:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new DeviceInfoPackage()
);
}- 在 JavaScript 端调用 Native 模块:
// www.javascriptcn.com code example
import { NativeModules } from 'react-native';
const { DeviceInfo } = NativeModules;
DeviceInfo.getDeviceInfo().then(result => {
console.log(result); // { brand: 'xx', model: 'xx', os: 'x.x.x' }
}).catch(error => {
console.log(error);
});在 JavaScript 文件中,我们通过 import 关键字来引用刚刚创建的 Native 模块。然后通过 NativeModules 对象来获取这个模块,最后我们可以使用 getDeviceInfo() 方法来获取设备信息。在这个方法中,我们使用了 Promise 对象来处理异步操作,通过 resolve() 和 reject() 方法来传递结果或错误信息。
iOS 封装步骤
- 创建一个 Objective-C 类来定义 Native 模块:
// www.javascriptcn.com code example
#import "React/RCTBridgeModule.h"
@interface DeviceInfoModule : NSObject <RCTBridgeModule>
@end
@implementation DeviceInfoModule
RCT_EXPORT_MODULE(DeviceInfo);
RCT_EXPORT_METHOD(getDeviceInfo: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
NSMutableDictionary *dictionary = [NSMutableDictionary new];
[dictionary setObject:[[UIDevice currentDevice] name] forKey:@"name"];
[dictionary setObject:[[UIDevice currentDevice] systemName] forKey:@"systemName"];
[dictionary setObject:[[UIDevice currentDevice] systemVersion] forKey:@"systemVersion"];
resolve(dictionary);
}
@end这个类使用 RCTBridgeModule 协议并实现 RCT_EXPORT_MODULE 和 RCT_EXPORT_METHOD 宏,它们分别用于指定模块名称和方法名以及暴露给 JavaScript 端。
- 在
AppDelegate.m中注册 Native 模块:
// www.javascriptcn.com code example
#import "DeviceInfoModule.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
[self addCustomModuleToBridge:bridge];
rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"App"
initialProperties:nil];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)addCustomModuleToBridge:(RCTBridge *)bridge {
[bridge registerModule:[[DeviceInfoModule alloc] init]];
}在这里,我们创建了一个 RCTBridge 对象并在其中注册了刚刚创建的 Native 模块。
- 在 JavaScript 端调用 Native 模块:
// www.javascriptcn.com code example
import { NativeModules } from 'react-native';
const { DeviceInfo } = NativeModules;
DeviceInfo.getDeviceInfo().then(result => {
console.log(result); // { name: 'xx', systemName: 'iOS', systemVersion: 'x.x.x' }
}).catch(error => {
console.log(error);
});在 JavaScript 中,我们和 Android 一样,使用 NativeModules 对象来获取刚刚创建的 Native 模块,并且使用 getDeviceInfo() 方法来获取设备信息。
总结
本文详细介绍了 React Native 模块 Native 模块封装的步骤,并且提供了 Android 和 iOS 两种平台的示例代码。通过封装 Native 模块,我们可以方便地扩展 React Native 的使用能力,提高开发效率。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/65a90181add4f0e0ff24ae4f