以下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”事件的监听。