Dyfan

React Native中Native与JS通信(Android篇)

2020-09-27

在开发react native过程中,免不了js和原生通信的需求,在介绍之前,我们先初始化一些通用代码

创建一个native类,继承自ReactContextBaseJavaModule,重写其getName方法,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
public class Test extends ReactContextBaseJavaModule {
private ReactContext mReactContext;

public Test(@NonNull ReactApplicationContext reactContext) {
super(reactContext);
this.mReactContext = reactContext;
}

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

/**
* 获取时间字符串
*/
private String getTimeMillis() {
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
return formatDate.format(date);
}
}

再定义一个NativeModulePackage.java类,将上面定义的module进行导出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
public class NativeModulePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new Test(reactContext));
return modules;
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
List<ViewManager> modules = new ArrayList<>();
return modules;
}
}

修改MainApplication.java

1
2
3
4
5
6
7
8
9
10
11
...
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new NativeModulePackage());//add this line
return packages;
}
...

在Android原生通信上有如下三种方式

一.使用NativeEventEmitter

在Test.java添加如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
@ReactMethod
public void getTime() {
String time = getTimeMillis();
WritableMap writableMap = new WritableNativeMap();
writableMap.putString("key", time);
sendEvent(mReactContext, "NativeTime", writableMap);
}
/**
* 使用原生端发送监听的方式
*
* @param reactContext
* @param eventName
* @param params
*/
private void sendEvent(ReactContext reactContext, String eventName, WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}

...

在js中添加如下代码:
先执行原生方法中定义的getTime方法,触发原生端发送监听事件,然后再由JS端接收监听事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
export default class Index extends Component {
componentDidMount() {
const eventEmitter = new NativeEventEmitter(NativeModules.TransModule);
this.eventEmitter = eventEmitter.addListener('NativeTime', (res) => {
console.log('native time==>', res);
});

}

componentWillUnmount() {
this.eventEmitter.remove();
}


render() {
return (
<View>
<TouchableOpacity onPress={() => {
NativeModules.TestModule.getTime();
}}>
<Text>监听native发送的事件</Text>
</TouchableOpacity>
</View>
);
}
}
二.使用callback回调

在Test.java添加如下方法:

1
2
3
4
5
6
7
8
9
/**
* 使用回调方式从原生获取数据
*
* @param callback
*/
@ReactMethod
public void callBackTime(Callback callback) {
callback.invoke(getTimeMillis());
}

在js中添加如下代码:

1
2
3
4
5
6
7
 <TouchableOpacity onPress={() => {
NativeModules.TransModule.callBackTime((res) => {
console.log('native time==>', res);
});
}}>
<Text>回调native返回的数据</Text>
</TouchableOpacity>
三.使用promise

在Test.java添加如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 使用promise方式从原生获取数据
*
* @param callback
*/
@ReactMethod
public void sendPromiseTime(Promise promise) {
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt("年龄", 20);
writableMap.putString("time", getTimeMillis());
promise.resolve(writableMap);
}

在js中添加如下代码:

1
2
3
4
5
6
 <TouchableOpacity onPress={async () => {
let res = await NativeModules.TransModule.sendPromiseTime();
console.log('native time==>', res);
}}>
<Text>promise方式获取原生数据</Text>
</TouchableOpacity>
上述三种方式通常根据不同的业务需要进行调整,如获取当前原生应用版本,可使用callback方式或者eventEmitter的方式,如果获取用户手机通讯录,或者从原生中的某个接口中获取数据,则可以使用promise的方式.
使用支付宝打赏
使用微信打赏

扫描二维码,分享此文章