首先:参照官网的原生模块和QZon的一篇文章:https://zhuanlan.zhihu.com/p/20259704
- Java和JS调用的顺序是通过C++的中间件翻译来实现的,js的代码最终翻译为Java的代码执行
- Java和js的调用都有个配置列表,以供他们互相调用,包括配置名称、id等等
下面以Android中Toast写一个简单的DEMO实现js和Java交互
Step 1
首先用Android Studio 打开RN工程目录下的android 工程
然后在as的工程目录下面新建一个java类XCToast继承ReactContextBaseJavaModule,RN工程里面所有的Java本地代码都在android目录下面编写,之后RN服务会自动为我们打包转化
- 在as中新建的类中定义我们的需要的方法showToast();
public class XCToast extends ReactContextBaseJavaModule {
public XCToast(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "XCToast";
}
@ReactMethod
public void showToast(String str) {
Toast.makeText(getCurrentActivity(),str,Toast.LENGTH_SHORT).show();
}
}
getName()是java本地module的名称,之后通过C++注册之后,就可以实现js和java的互掉。
showToast是我们自己编写的方法,要加上@ReactMethod注解才能被RN识别调用,参数str是从js传递过来显示子在toast中的内容
- 下一步需要创建一个类继承于ReactPackage,这个类用于把我们所有本地的module注册进去,才可以在js中调用
public class XCPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> list = new ArrayList();
list.add(new XCToast(reactContext));
return list;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return null;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return null;
}
}
- 然后需要在MainApplication中把Package添加进去
public class MainApplication extends Application implements ReactApplication {
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(),
new XCPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
这样才算正式的把我们的写的module注册到应用中去。可以看到RN的默认是有一个MainReactPackage的,点击进去的源码看到有RN定义了许多默认的模块来提供自己的通讯。
public List<ModuleSpec> getNativeModules(final ReactApplicationContext context) {
return Arrays.asList(
new ModuleSpec(AccessibilityInfoModule.class, new Provider<NativeModule>() {
@Override
public NativeModule get() {
return new AccessibilityInfoModule(context);
}
}),
new ModuleSpec(AppStateModule.class, new Provider<NativeModule>() {
@Override
public NativeModule get() {
return new AppStateModule(context);
}
}),
new ModuleSpec(AsyncStorageModule.class, new Provider<NativeModule>() {
@Override
public NativeModule get() {
return new AsyncStorageModule(context);
}
}),
new ModuleSpec(CameraRollManager.class, new Provider<NativeModule>() {
@Override
public NativeModule get() {
return new CameraRollManager(context);
}
}),
.....
Step 2
接下来是js层面的代码:
新建一个js文件,进行再次封装:
mport {NativeModules} from 'react-native'
export default NativeModules.XCToast;
之后就可以导入调用了:
XCToast.show("js调用java")
此处导入的如果是子模块就需要{}包裹
大功告成!