美文网首页
React native与原生应用(二)--JS与原生应用间传递

React native与原生应用(二)--JS与原生应用间传递

作者: Qi0907 | 来源:发表于2017-09-19 16:28 被阅读0次

    参考react native中文网“原生模块(Android)” http://reactnative.cn/docs/0.48/native-modules-android.html#content,JS端与原生模块之间通信,主要有三种方法:
    (1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript。
    (2)使用Promise来实现。
    (3)原生模块向JavaScript发送事件。

    一、添加两个必要类
    在使用这三种通信方法之前,在原生应用上需要实现三个类来与JS端进行交互:


    Paste_Image.png
    1. new ReactPackages类
      在上一篇中,集成到现有原生应用中创建了一个类
    ReactNativeInAndroidActivity extends ReactActivity implements DefaultHardwareBackBtnHand
    

    在onCreate时,创建了一个ReactInstanceManager,并需要加入一个我们定义的一个ReactPackages

    mReactInstanceManager = ReactInstanceManager.builder()
            .setApplication(getApplication())
            .setCurrentActivity(this)
            .setBundleAssetName("index.android.bundle")
            .setJSMainModuleName("currentDetail")
            .addPackage(new MainReactPackage())
            .addPackage(new AndroidNativePackage())//我们自己ReactPackages
            .setUseDeveloperSupport(true)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .setDefaultHardwareBackBtnHandler(this)
            .build();
    

    new ReactPackages的实现可参考http://blog.csdn.net/qq_25827845/article/details/52963594,有一个简单的小例子来介绍用法。
    在这个类中最关键的函数就是createNativeModules,
    在该函数中我们需要new一个ReactContextBaseJavaModule类

    public class AndroidNativePackage implements ReactPackage {
    @Override
        public List<NativeModule>    createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList<>();
            modules.add(new CurrentModule(reactContext));
            return modules;
        }
    }
    
    1. new ReactContextBaseJavaModule类
    public class CurrentModule extends ReactContextBaseJavaModule
    

    在这个类中有两个重要的函数:
    a.

    public CurrentModule(ReactApplicationContext reactContext) {
        super(reactContext);
        //要把上下文传递给ReactActivity类即ReactNativeInAndroidActivity,否则ReactNativeInAndroidActivity获得不了上下文
        ReactNativeInAndroidActivity.mReactContext = reactContext;
    }
    

    b.

    @Override
    public String getName() {
        //返回的这个字符串在JavaScript端标记这个模块,在JS端可以通过NativeModules.CurrentDetailModuleg访问到这个模块
        return "CurrentDetailModule";
    }
    

    c. JS端通过上面的方法可以访问到CurrentModule这个类了,具体调用那个功能函数就需要使用下面这种方法

    @ReactMethod //需要使用注解@ReactMethod。方法的返回类型必须为void
    public void function() {
         处理逻辑
    }
    

    JS可以通过NativeModules.CurrentDetailModule.function来访问这个函数

    二、RN前端与原生模块之间通信
    1、回调函数Callback,它提供了一个函数来把返回值传回给JavaScript
    原生应用:

    @ReactMethod 
    public void getLoginState(Callback callback)
     {
         try { 
               WritableMap map = Arguments.createMap(); 
               map.putString("isLogin", "0"); 
               callback.invoke(map);//把map传回给JS
          } catch (IllegalViewOperationException e) { 
               Logger.i("React-Native:getLoginState")); 
          } 
    }
    

    JS:

    //可以访问到原生应用的CurrentDetailModule类
    var bridge = NativeModules.CurrentDetailModule;
    //访问CurrentDetailModule类中getLoginState函数,把原生传给JS的map赋值到properties
    bridge.getLoginState((properties) => {
       //从properties中取得key对应的value的值进行判断
       if (properties["isLogin"] == '0') {
            bridge.gotoLogin();
     } else { 
    // 
    }
    })
    
    1. 原生模块向JavaScript发送事件
      原生模块可以在没有被调用的情况下往JavaScript发送事件通知。最简单的办法就是通过RCTDeviceEventEmitter,这可以通过ReactContext来获得对应的引用
      原生应用:
    @ReactMethod 
    public void sendDataToJs() { 
        WritableMap params = Arguments.createMap(); 
        params.putString("SendData", "1234");//"SendData"是key值,通过它获得value值
        //"eventName"是JS端监听的事件的名称
        mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("eventName", params); 
    }
    

    JS:

    componentWillMount() {//JS组件还没有开始渲染时
        this.callNative.bind(this); 
        //注册监听事件,监听事件名称为'eventName',监听处理函数
        onScanningResult
        DeviceEventEmitter.addListener('eventName', this.onScanningResult);
    }
    
    onScanningResult = (e) => { //e是从原生应用传过来的数据
        //通过e.SendData获取key为SendData的value值
        this.setState({ money: e.SendData, }); 
    }
    

    相关文章

      网友评论

          本文标题:React native与原生应用(二)--JS与原生应用间传递

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