现如今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) });