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<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new QQNativeApiModule(reactContext));
}
@Override
public List<ViewManager> 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<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> 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 <Foundation/Foundation.h>
#import <React/RCTBridge.h>
@interface QQNativeApi:NSObject<RCTBridgeModule>
@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。');
}
});
}
网友评论