react native与原生native交互
2018-11-02 本文已影响2人
weioule
现如今React-Native尚未成熟,在开发过程中自然少不了与原生native的交互与数据传递。学习过程中查了一些资料,主要有以下三种方式:
方式 / 优点 / 缺点
事件方式:RCTDeviceEventEmitter 可任意时刻传递,Native主导控制 个人觉得此种方式缺点小
CallBack回调方式 JS调用一次,Native返回一次 CallBack为异步操作,返回时机不确定
Promises 方式 JS调用一次,Native返回一次 每次使用需要JS调用一次
步骤:
1、JS文件导入NativeModules组件
import {NativeModules} from 'react-native';
2、在android中创建一个类继承自ReactContextBaseJavaModule,并定义一些native方法供RN调用。
public class ExampleInterface extends ReactContextBaseJavaModule {
private ReactApplicationContext mContext;
public ExampleInterface(ReactApplicationContext reactContext) {
super(reactContext);
this.mContext = reactContext;
}
@Override
public String getName() {
return "ExampleInterface";
}
下面的NativeModules.ExampleInterface就是获取这个类的实例,而getName就是返回该类的名字
3、在你自定义的ReactPackage的实现类的createNativeModules方法里添加ExampleInterface的实例并返回
public class AnExampleReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
ArrayList<NativeModule> nativeModules = new ArrayList<>();
nativeModules.add(new ExampleInterface(reactContext));
return nativeModules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
public List<Class<? extends JavaScriptModule>> createJSModules(){
return Collections.emptyList();
}
}
4、然后在你自定义的ReactApplication的实现类的getPackages方法里返回AnExampleReactPackage的实例
public class ReactApp extends Application implements ReactApplication {
private ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
/*将我们自定的包管理加入*/
new AnExampleReactPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index.android";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, false);
}
}
交互方式的具体使用:
1 RCTDeviceEventEmitter:
/**
* 向RN发送消息
*
* @param msg
*/
private void sendMsgToRN(String msg) {
mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("AndroidToRNMessage", msg);
}
/**
*JS接收回调
*/
componentWillMount() {
DeviceEventEmitter.addListener('AndroidToRNMessage', this.handleAndroidMessage.bind(this));
}
handleAndroidMessage(androidMeg) {
this.setState({msg: androidMeg});
}
2 CallBack回调:
/**
* native端让JS端调用的方法,并将msg回调给JS
*/
@ReactMethod
public void handleCallback(String msg, Callback callback) {
callback.invoke(msg);
}
/**
* JS端调用native端handleCallback方法
*/
NativeModules.ExampleInterface.handleCallback('JS Callback', (msg) => {
alert(msg);
});
3 Promises 方式:
/**
*ative端让JS端调用的方法,用Promise时,Promise参数需要放在最后一个参数里,否则JS接搜不到消息
*/
@ReactMethod
public void handlePromise(String msg, Promise promise) {
try {
promise.resolve(msg);
} catch (Exception e) {
promise.reject(e);
}
}
/**
* NativeModule.ExampleInterface.handlePromise 返回的是一个Promise对象,
* JS端通过then接口来获取Promise的数据。
*/
NativeModules.ExampleInterface.handlePromise('Promise')
.then((msg) => { alert(msg); })
.catch((error) => { console.log(error) });