美文网首页
React Native从零单排6 原生交互

React Native从零单排6 原生交互

作者: 房祥_a7f1 | 来源:发表于2021-05-13 21:41 被阅读0次
    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。');
                }
        });
    }
    

    相关文章

      网友评论

          本文标题:React Native从零单排6 原生交互

          本文链接:https://www.haomeiwen.com/subject/lraxjltx.html