React Native要想与Android进行通信,需要先做通用的准备工作,主要分为如下三步:
- 在原生端定义继承自ReactContextBaseJavaModule的ToastExample 类,在ToastExample 类里,定义交互的方法。
public class ToastExample extends ReactContextBaseJavaModule {
public static final String LONG_TIME = "LONG";
public static final String SHORT_TIME = "SHORT";
public static final String MESSAGE = "MESSAGE";
public ToastExample(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* 该方法的返回值是在RN中需要这个值来调用该类的方法
* @return
*/
@Override
public String getName() {
return "ToastForAndroid";
}
@Override
public boolean canOverrideExistingModule() {
return true;
}
}
- 定义继承自ReactPackage的ExampleReactNativePackage类,将ToastExample 实例添加到集合;
public class ExampleReactNativePackage implements ReactPackage {
private ToastExample mToastExample;
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
mToastExample = new ToastExample(reactContext);
modules.add(mToastExample);
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
- 定义继承自ReactApplication的MainApplication类,重写getPackages方法,将ExampleReactNativePackage实例添加到集合中。
public class MainApplication extends Application implements ReactApplication {
public static final ExampleReactNativePackage exampleReactNativePackage = new ExampleReactNativePackage();
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(),
exampleReactNativePackage
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
下面我们具体来了解React Native和Android之间的几种通信方式,
第一种:
- 原生代码,在ToastRxample.java中添加下面方法。
@ReactMethod
public void show(int duration){
Toast.makeText(getReactApplicationContext(), "message:"+duration,duration).show();
}
注:@ReactMethod表示该方法可以被RN调用。
- RN(React Native的简称,下同)代码,在App.js中添加调用代码,
import React, {Component} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
AppRegistry,
TouchableOpacity,
ToastAndroid,
NativeModules,
DeviceEventEmitter
} from 'react-native';
type Props = {};
export default class App extends Component<Props> {
constructor(props){
super(props);
this.state = {
text1:"ToastForAndroid",
}
this.componenWillMount();
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>Android与React Native之间的通信有以下几种方式:</Text>
<TouchableOpacity onPress={this._onPressButton.bind(this)}>
<Text style={styles.hello}>{this.state.text1}</Text>
</TouchableOpacity>
</View>
);
}
_onPressButton(){
NativeModules.ToastForAndroid.show(1000);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
flexDirection:'column',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
hello:{
fontSize: 16,
textAlign:'center',
margin: 10,
},
title:{
fontSize:20,
color: '#f00',
margin:20,
}
});
上面的代码很好理解,方法_onPressButton是最重要的一块,RN通过NativeModus.[ToastExample中getName的返回值].[ToastExample中的方法]来调用原生的方法。
第二种:
- 原生代码,
@ReactMethod
public void testAndroidCallbackMethod(String msg,Callback callback){
Toast.makeText(getReactApplicationContext(), msg, Toast.LENGTH_LONG).show();
callback.invoke("abc");
}
callback是RN提供的,我们可以利用Callback返回数据给RN。
- RN代码,代码和上变的类似,只是调用的方法不一样而已,调用了Android的testAndroidCallbackMethod方法。
_onPressButton2(){
NativeModules.ToastForAndroid.testAndroidCallbackMethod("HelloJack",(result)=>{
this.setState({text2:result});
})
}
result就是Android中传过来的数据'abc'。
第三种:
- 原生代码
@ReactMethod
public void testAndroidPromiseMethod(String msg, Promise promise){
Toast.makeText(getReactApplicationContext(), msg, Toast.LENGTH_SHORT).show();
String result = "高娟娟";
promise.resolve(result);
}
- RN代码
_onPressButton3(){
NativeModules.ToastForAndroid.testAndroidPromiseMethod("abcx").then((result)=>{
this.setState({text3:result});
}).catch((error)=>{
this.setState({text:'error'});
})
}
第四种:
- 原生代码
public static final String LONG_TIME = "LONG";
public static final String SHORT_TIME = "SHORT";
public static final String MESSAGE = "MESSAGE";
@Override
public Map<String,Object> getConstants(){
//让js那边能够使用这些常量
Map<String,Object> constans = new HashMap<>();
constans.put(LONG_TIME, Toast.LENGTH_LONG);
constans.put(SHORT_TIME, Toast.LENGTH_SHORT);
constans.put(MESSAGE, "这是MESSAGE的值");
return constans;
}
private void sendEvent(ReactApplicationContext reactContext, String eventName, WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,params);
}
- RN代码,设置监听,在监听中获取ToastForAndroid中的一些值。
constructor(props){
super(props);
this.componenWillMount();
}
componenWillMount(){
DeviceEventEmitter.addListener('EventName',function (msg) {
console.log(msg);
let rest = NativeModules.ToastForAndroid.MESSAGE;
ToastAndroid.show("DeviceEventEmitter收到的消息:"+"\n"+rest,ToastAndroid.SHORT);
});
}
_onPressButton4(){
NativeModules.ToastForAndroid.sendEvent();
}
测试结果会发现,监听中获取到的rest值是“这是MESSAGE的值”。
源码地址
我也是初学阶段,希望这些对大家有用,有不懂的地方,大家可以一起讨论。
网友评论