android原生与React-Natived的JS交互

以下React-Natived中的统称js;

在交互之前先做项目配置:

1、新建OpenNativeModule类,如:

public class OpenNativeModule extends ReactContextBaseJavaModule {
    private ReactContext mReactContext;

    public OpenNativeModule(ReactApplicationContext context) {
        super(context);
        this.mReactContext = context;
    }

    @Override
    public String getName() {
        return "OpenNativeModule";
    }

    /**
     * rn调用原生方法
     *
     * @param flag
     */
    @ReactMethod
    public void openNativeVC(int flag) {
        if (1 == flag) {
            Intent intent = new Intent();
            intent.setClass(mReactContext, MineActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mReactContext.startActivity(intent);
        }
    }
 /**
     * 通过Callbacks的方式由原生向RN传值
     *
     * @param errorCallback
     * @param successCallback
     */
    @ReactMethod
    public void jsCallNativeMethod(
            Callback errorCallback,
            Callback successCallback) {
        try {
            successCallback.invoke(10, 11, "收到", "ss");
        } catch (IllegalViewOperationException e) {
            errorCallback.invoke(e.getMessage());
        }

    }

    /**
     * 通过Promises的方式由原生向RN传值
     *
     * @param promise
     */
    @ReactMethod
    public void jsCallNativeMethodTwo(Promise promise) {
        try {
            WritableMap map = Arguments.createMap();
            map.putDouble("relativeX", 1);
            map.putDouble("relativeY", 1);
            map.putDouble("width", 2);
            map.putDouble("height", 3);
            promise.resolve(map);
        } catch (IllegalViewOperationException e) {
            promise.reject(e);
        }
    }

}

2、创建TestReactPackage类,如:

public class TestReactPackage implements ReactPackage {
    public OpenNativeModule openNativeModule;

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        openNativeModule = new OpenNativeModule(reactContext);
        modules.add(openNativeModule);
        return modules;
    }

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

3、MyApplication中的配置:

public class MyApplication extends Application implements ReactApplication {
    private static MyApplication application;
    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
                    new SvgPackage(),
                    testReactPackage
//                    new TestReactPackage()
            );
        }

        @Nullable
        @Override
        protected String getJSBundleFile() {
            return super.getJSBundleFile();
        }
    };

    private static TestReactPackage testReactPackage = new TestReactPackage();

    public static TestReactPackage getTestReactPackage() {
        return testReactPackage;
    }

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

    public static MyApplication getApplicationC() {
        return application;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
        SoLoader.init(this, false);
    }

}

一、js调用原生方法传值:

import {NativeModules} from 'react-native';

var nativeModule = NativeModules.OpenNativeModule;

//点击事件可以直接调此方法
jumpToNativeView() {
   //调用原生openNativeVC执行原生操作
   nativeModule.openNativeVC(1);
}

二、原生给js传值

原生给js传值总共有三种方法,分别是通过Callbacks的方式、通过Promises的方式、通过发送事件的方式;

先看下三种方式的区别:

方式

缺点

优点

通过Callbacks的方式

只能传递一次

传递可控,JS模块调用一次,原生模块传递一次

通过Promises的方式

只能传递一次

传递可控,JS模块调用一次,原生模块传递一次

通过发送事件的方式

原生模块主动传递,JS模块被动接收

可多次传递

 

方式一:通过Callbacks的方式

 

原生代码参考OpenNativeModule类,方法有注释;

js代码:

import {NativeModules} from 'react-native';

var nativeModule = NativeModules.OpenNativeModule;

//js点击事件直接调此方法
  jumpToNativeView() {
 //通过Callbacks的方式获取原生传的值===成功
    nativeModule.measureLayout(
                       (msg) => {
                       alert(msg);
                       },
                       (x, y, width, height) => {
                      alert(x + ':' + y + ':' + width + ':' + height);
                       });
}

 

 

 

 方式二、通过Promises的方式

原生代码参考OpenNativeModule类,方法有注释;

js代码:

import {NativeModules} from 'react-native';

var nativeModule = NativeModules.OpenNativeModule;


//js点击事件直接调此方法
jumpToNativeView() {
//通过Promises的方式由原生向RN传值===成功
      nativeModule.measureLayoutPro().then(e=>{
         alert("Promises"+ e.relativeX + ':' + e.relativeY + ':' + e.width + ':' + e.height);
         this.setState({
           relativeX:e.relativeX,
           relativeY:e.relativeY,
           width:e.width,
           height:e.height,
         })
       }).catch(error=>{
        alert("Promises"+msg);
       });
  }

 

方式三、通过发送事件的方式

js代码:

import {DeviceEventEmitter} from 'react-native';

//通过发送事件的方式由原生向RN传值
  componentWillMount(){
      DeviceEventEmitter.addListener('Event_Call', this.onEvent_Async);
    }

  onEvent_Async = (e) => {
      alert(JSON.stringify(e));
  }

原生代码 如:

第一种:需要在OpenNativeModule类中定义sendEvent方法

/**
 * 发送事件
 * @param eventName  事件Flag
 * @param params  要传的参数
 */
 public void sendEvent(String eventName, @Nullable Object params) {
        ReactContext reactContext = MyApplication.getApplicationC().getReactNativeHost()
                .getReactInstanceManager().getCurrentReactContext();
     if (reactContext == null){
       return;
     }
     reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
 }

发送事件的代码:

 // 发送事件===sendEvent方法定义在了OpenNativeModule类中,方法如下
   WritableMap et = Arguments.createMap();
   et.putInt("key1", 11);
   et.putInt("key2", 22);
   et.putString("key3", "参数3");

  MyApplication.getTestReactPackage().openNativeModule.sendEvent("EventName_Async", et);

第二种发送事件直接调用

  // 发送事件
  WritableMap et = Arguments.createMap();
  et.putInt("key1", 11);
  et.putInt("key2", 22);
  et.putString("key3", "参数3");
  MyApplication.getApplicationC().getReactNativeHost()
        .getReactInstanceManager().getCurrentReactContext()
        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
        .emit("EventName_Async", et);

通过发送事件传值需要注意:

如果在JS中有多处注册了onScanningResult事件,那么当原生模块发出事件后,这几个地方会同时收到该事件。不过大家也可以通过DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult) 来移除对名为“onScanningResult”事件的监听。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值