本文仅用于帮助Android开发者对接RN项目
打开React Native项目
1. 搭建React Native开发环境
2. 使用Android Studio打开RN项目
下图是RN项目的目录结构:
RN项目下的android目录才是Android的项目结构,使用Android Studio打开该目录即可。
RN调用Android
1. 自定义Module类
新建class继承ReactContextBaseJavaModule。
- getName()返回值与RN调用的module名一致(类名不需要一致)
- 定义方法,方法名与RN调用的方法名一致,且用@ReactMethod注解
public class LoginModule extends ReactContextBaseJavaModule {
private static final String TAG = "LoginModule";
private Context reactContext;
public LoginModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "LoginSuccessModule";
}
@Override
public boolean canOverrideExistingModule() {
return true;// 覆盖已有的module
}
/**
* 登录成功
*/
@ReactMethod
public void loginSuccess() {
Log.d(TAG, "loginSuccess: ");
}
}
2. 自定义ReactPackage类
新建class实现ReactPackage,在createNativeModules()中返回的List添加LoginModule对象。
public class MyReactPackage implements ReactPackage {
public static List<NativeModule> list = new ArrayList<>();
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
list.add(new LoginModule(reactContext));// 添加module
return list;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
3. 注册ReactPackage
RN的Application会实现ReactApplication,和这个接口的getReactNativeHost()方法,它需要return一个ReactNativeHost对象,以上操作是RN自动完成的。
ReactNativeHost中getPackages()方法的返回值,就是RN调用Android的功能模块的集合,比如RN集成微信登录后,会自动在这里添加WeChatPackage对象。我们只需把自定义的ReactPackage也添加到List即可。
public class MainApplication extends Application implements ReactApplication {
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new WeChatPackage(),// 微信模块
new MyReactPackage()// 自定义模块
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
}
ReactApplication: getReactNativeHost() -> ReactNativeHost: getPackages() -> MyReactPackage: createNativeModules -> LoginModule: loginSuccess()
这样,我们定义的module和方法就注册完成了。
Android调用RN
官方用法
RN调用Android需要module名和方法名相同,而Android调用RN只需要方法名相同
//WritableMap params = Arguments.createMap();// RN的Map
WritableArray params = Arguments.createArray();// RN的Array
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
params类型除了RN提供的WritableMap和WritableArray,也可以是Java包装类,与RN接收的类型一致即可。
进化用法
以上即可调用RN方法。以下是本人的实现方式,经实践目前未出现问题
考虑到ReactContext不容易获取,提高内聚,进行封装如下:
1. 新建EventEmitter类,作为调用RN的统一入口
2. 定义静态ReactContext
3. 定义静态调用方法
public class EventEmitter {
private static final String TAG = "EventEmitter";
public static ReactContext mReactContext;// 在ReactPackage中的createNativeModules()初始化
/**
* 显示loading
*
* @param data 1显示,非1隐藏
*/
public static void showLoading(int data) {
if (mReactContext == null) {
Log.e(TAG, "ReactContext is null");
return;
}
mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("loadingNotification", data);
}
}
4. 在自定义ReactPackage的createNativeModules()方法中为ReactContext赋值(ReactApplicationContext是ReactContext的子类)
public class MyReactPackage implements ReactPackage {
public static List<NativeModule> list = new ArrayList<>();
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
EventEmitter.mReactContext = reactContext;// 初始化ReactContext
list.add(new LoginModule(reactContext));// 添加module
return list;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
这样,在EventEmitter类中添加方法,就可以像工具类一样随心所欲的调用RN了。