React Native 原生模塊封裝:支付寶示例

React Native自己已經提供不少可用的模塊和組件,有一部分咱們須要的模塊和組件仍然沒法直接提供,須要藉助原生的代碼來提供。封裝原生模塊和視圖導出使用,也可讓React Native擁有android和ios平臺的強大生態鏈和使用衆多第三方類庫。java

原生模塊

如下以支付寶支付模塊爲實例react

android支付寶

模塊實現

AlipayModule.javaandroid

// 模塊繼承自ReactContextBaseJavaModule
public class AlipayModule extends ReactContextBaseJavaModule {

  // 默認構造方法
  public AlipayModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  // 模塊名
  @Override
  public String getName() {
    return "AlipayModule";
  }

  // 添加@ReactMethod註解導出方法
  // promise需放在最後
  @ReactMethod
  public void pay(final String orderInfo, final Promise promise) {
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        PayTask alipay = new PayTask(getCurrentActivity());
        Map<String, String> result = alipay.payV2(orderInfo,true);
        Log.i("AlipayModule", "resultStatus: " + result.get("resultStatus"));
        if ("9000".equals(result.get("resultStatus"))) {
          promise.resolve(true);
        } else {
          promise.resolve(false);
        }
      }
    };
    Thread thread = new Thread(runnable);
    thread.start();
  }

}
複製代碼

模塊註冊

MyReactPackage.javaios

// 實現ReactPackage接口
// 用於註冊導出的模塊和視圖
public class MyReactPackage implements ReactPackage {

  // 原生模塊註冊
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    return Arrays.<NativeModule>asList(
        new AlipayModule(reactContext)
    );
  }

  // 原生視圖註冊
  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Arrays.<ViewManager>asList();
  }
}
複製代碼

包註冊

在MainApplication getPackages方法中添加new MyReactPackage()react-native

ios支付寶

模塊實現

AlipayModule.hpromise

#import <React/RCTBridgeModule.h>

@interface AlipayModule : NSObject<RCTBridgeModule>

@end
複製代碼

AlipayModule.mbash

#import "AlipayModule.h"
#import <AlipaySDK/AlipaySDK.h>

@interface AlipayModule()

@end

@implementation AlipayModule

// 添加宏,導出模塊
RCT_EXPORT_MODULE();
  
// 使用宏,導出方法,resolve和reject爲promise方法
RCT_EXPORT_METHOD(pay: (NSString *) orderInfo resolver: (RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject)
{
  [[AlipaySDK defaultService] payOrder:orderInfo fromScheme:@"本app的schema" callback:^(NSDictionary *resultDic)
  {
    if ([@"9000" isEqualToString: [resultDic valueForKey:@"resultStatus"]]) {
      resolve(@(YES));
    } else {
      resolve(@(NO));
    }
  }];
}

@end
複製代碼

js層

方法導出

Alipay.tsapp

import {NativeModules} from 'react-native';

export interface Alipay {
  pay(orderInfo: string): Promise<boolean>;
}

export const Alipay = NativeModules.AlipayModule as Alipay;
複製代碼

js層使用

import Alipay from './Alipay';

try {
    const result = await Alipay.pay(orderInfo);
    if (result) console.log('支付成功');
} catch(e) {
    console.error(e);
}
複製代碼

原生模塊導出相對而言仍是很是簡單的,在上面支付寶支付的實例中演示了導出一個簡單的模塊和promise在原生代碼中的注入和在js層的使用。ide

原生js交互

原生調用js

js中調用模塊代碼,模塊中直接導出便可,有時候咱們也會須要在原生代碼中去調用js的代碼,例如作事件通知等。ui

android調用js

事件名爲js層監聽的名字,值能夠爲int、float等,與原生方法一直

reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit("事件名", 值);
複製代碼

js監聽android調用

const listener = DeviceEventEmitter.addListener('事件名',
        data => console.log('android調用', data));
// 調用完成移除監聽 
listener.remove();
複製代碼

ios調用js

模塊.h文件

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

// 修改.h中NSObject爲RCTEventEmitter
@interface XXXModule : RCTEventEmitter<RCTBridgeModule>

@end

複製代碼

模塊.m文件

// 添加支持事件名
- (NSArray<NSString *> *)supportedEvents
{
  return @[@"event1", @"event2"];
}

// 事件發送
// float body [NSNumber numberWithFloat:num]
[self sendEventWithName:@"event1" body:body];
複製代碼

js監聽ios調用

// 獲取模塊監聽者
// XXXModule爲模塊名稱,與導出的名字一致
const eventEmitter = new NativeEventEmitter(NativeModules.XXXModule);

const listener = eventEmitter.addListener('事件名',
          data => console.log('ios調用', data));
// 監聽完成後移除 
listener.remove();
複製代碼

ios和android發送事件封裝方法不同,在js層監聽方法也不同,因此須要注意平臺,通常事件是在耗時操做過程當中監聽,在開始時候開始監聽,在結束後應立刻移除監聽。

相關文章
相關標籤/搜索