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 模块:
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 模块:
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 模块:
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 模块:
#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 模块:
#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 模块:
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 的使用能力,提高开发效率。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a90181add4f0e0ff24ae4f