创建模块
在android部分新建一个类继承ReactContextBaseJavaModule,并且实现getName方法,这个方法的返回值在js端代表这个模块
public class AndroidNative extends ReactContextBaseJavaModule {
public AndroidNative(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "AndroidNative";
}
}
JS端想调用android的方法,必须使用注解@ ReactMethod标示此方法,这个方法必须是void的。RN的跨语言访问是异步进行的,想要给js返回一个值的唯一方法是回调函数或发送事件。
@ReactMethod
public void sendMessageToNative(String message) {
Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
注册模块
在Java这边做的最后一件事就是注册这个模块,如果不注册,在js端是无法使用的。新建一个类实现ReactPackage接口,并在createNativeModules方法中添加此模块
public class AndroidNativeReactPackage implements ReactPackage{
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new AndroidNative(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
在MainApplication.java文件的getPackages方法中加入此package,
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new AndroidNativeReactPackage()
);
}
import {NativeModules} from 'react-native';
//在需要的地方调用下面的代码
NativeModules.AndroidNative.sendMessageToNative("RN调用原生Toast")
为了在js端使用方便,可以将之封装成一个js模块,这样就用每次使用都写import {NativeModules} from 'react-native';
android 端调用RN JS代码
原生模块在没有被调用的情况下主动往JS 端发送事件。最简单的办法就是通过RCTDeviceEventEmitter,这可以通过ReactContext来获得对应的引用。
在andorid端的核心代码如下:
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("约定的事件名字",param);
JS端可以通过使用DeviceEventEmitter模块来监听事件
import {DeviceEventEmitter} from 'react-native';
componentWillMount() {
DeviceEventEmitter.addListener('约定的事件名字', this.onCompleted.bind(this));
}
onCompleted(result) {
alert(result)
}
从startActivityForResult中获取结果
如果你使用startActivityForResult调起了一个activity并想从其中获取返回结果,那么你需要监听onActivityResult事件。具体的做法是继承BaseActivityEventListener或是实现ActivityEventListener
public class TestNative extends ReactContextBaseJavaModule implements ActivityEventListener{
public TestNative(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addActivityEventListener(this);
}
@Override
public String getName() {
return null;
}
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
}
@Override
public void onNewIntent(Intent intent) {
}
}