React Native从零单排6 原生交互

RN版本:0.64
系统:Win10

前言

React Native应用大部分操作都可以在JS端完成,但是也有一些复杂的功能是需要原生端来完成的,比如Apple 或 Android 支付、打开第三方App或者为图像处理等内容编写一些高性能多线程代码。
接下来我们以加入QQ群为例,分别从Android和Ios两个方面看一下如何实现原生交互。

1.Android

创建一个继承了ReactContextBaseJavaModule的 Java 类并命名为QQNativeApiModule.java,放置到android/app/src/main/java/com/your-app-name/目录下:QQNativeApiModule.java,在它的内部实现加入qq群的方法。

public class QQNativeApiModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;

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

    @Override
    public String getName() {
        return "QQNativeApi";
    }
    // 要导出一个方法给 JavaScript 使用,Java 方法需要使用注解@ReactMethod。方法的返回类型必须为void
    @ReactMethod
    public void joinQQGroup(String key, Promise promise) {
        boolean success;
        String msg = null;
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
        try {
            reactContext.startActivity(intent);
            success = true;
        } catch (Exception e) {
            // 未安装手Q或安装的版本不支持
            success = false;
        }

        WritableMap writableMap = new WritableNativeMap();
        writableMap.putBoolean("success", success);
        writableMap.putString("msg", msg);
        //返回给RN处
        promise.resolve(writableMap);
    }
}

创建一个新的 Java 类并命名为QQNativeApiPackage.java,放置到android/app/src/main/java/com/your-app-name/目录下,其具体代码如下:

public class QQNativeApiPackage implements ReactPackage {

    @Override
    public List createNativeModules(ReactApplicationContext reactContext) {
        return Arrays.asList(new QQNativeApiModule(reactContext));
    }

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

这个 package 需要在MainApplication.java文件的getPackages方法中提供。这个文件位于你的 react-native 应用文件夹的 android 目录中。具体路径是: android/app/src/main/java/com/your-app-name/MainApplication.java

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          packages.add(new QQNativeApiPackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
}

JS端调用:

// JoinQQGroup.js
import { NativeModules } from 'react-native';

const QQNativeApi = NativeModules.QQNativeApi;

const joinQQGroup = (key) =>{
    QQNativeApi.joinQQGroup(key).then(rst => {
        if (!rst.success) {
              global.Toast('没有找到QQ。');
        }
    }
}

2.Ios

自定义接口类QQNativeApi.h,需要实现RCTBridgeModule协议,导入RCT_EXPORT_MODULE宏定义.

#import 
#import 

@interface QQNativeApi:NSObject

@end

新建QQNativeApi.m,实现加入QQ群方法

#import "QQNativeApi.h"

@implementation QQNativeApi

//  必须实现
RCT_EXPORT_MODULE();

RCT_REMAP_METHOD(joinQQGroup,
                 uin:(NSString *)uin
                 key:(NSString *)key
                 joinQQGroupResolve:(RCTPromiseResolveBlock)joinQQGroupResolve
                 joinQQGroupReject:(RCTPromiseRejectBlock)joinQQGroupReject) {
  NSString *urlStr = [NSString stringWithFormat:@"mqqapi://card/show_pslcard?src_type=internal&version=1&uin=%@&key=%@&card_type=group&source=external", uin, key];
  NSURL *url = [NSURL URLWithString:urlStr];
  dispatch_async(dispatch_get_main_queue(), ^{
    if([[UIApplication sharedApplication] canOpenURL:url]){
      [[UIApplication sharedApplication] openURL:url];
    }
  });
  joinQQGroupResolve([self Success:@YES]);
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end

JS调用

// JoinQQGroup.js
import { NativeModules } from 'react-native';

const QQNativeApi = NativeModules.QQNativeApi;
const joinQQGroup = (key) =>{
    QQNativeApi.joinQQGroup(this.state.groupUin,this.state.groupKey,)
        .then(rst => {
            if (!rst.success) {
              global.Toast('没有找到QQ。');
            }
    });
}

你可能感兴趣的:(React Native从零单排6 原生交互)