初始化一个RN项目以后,接下来想要让Android与React Native通信
写一个继承自ReactContextBaseJavaModule类的子类,重写getName方法
- package com.awesomeproject
-
- import android.util.Log
- import android.widget.Toast
- import com.facebook.react.bridge.Arguments
- import com.facebook.react.bridge.ReactApplicationContext
- import com.facebook.react.bridge.ReactContextBaseJavaModule
- import com.facebook.react.bridge.ReactMethod
- import com.facebook.react.modules.core.DeviceEventManagerModule
-
- class CustomModule(reactContext: ReactApplicationContext?) :
- ReactContextBaseJavaModule(reactContext) {
-
- companion object {
- const val TAG = "CustomModule"
- }
-
- /**
- * 返回注册module的名字
- */
- override fun getName(): String {
- return "CustomModule"
- }
-
-
- @ReactMethod
- fun sendEvent(name: String?, msg: String?) {
- if (name != null && msg != null) {
- Toast.makeText(
- reactApplicationContext,
- "the name is $name: the msg is $msg",
- Toast.LENGTH_SHORT
- ).show()
- }
- }
-
- @ReactMethod
- fun sendMessageToReactNative(msg: String?) {
- val params = Arguments.createMap()
- Log.i(TAG, "msg is $msg")
- params.putString("name", msg)
- // 传递给js端参数
- reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
- .emit("customEventName", params)
- }
- }
重写一个继承自ReactPackage类的子类,重写createNativeModules和createViewManagers方法
- package com.awesomeproject
-
- import android.view.View
- import com.facebook.react.ReactPackage
- import com.facebook.react.bridge.NativeModule
- import com.facebook.react.bridge.ReactApplicationContext
- import com.facebook.react.uimanager.ReactShadowNode
- import com.facebook.react.uimanager.ViewManager
-
- class CustomPackage : ReactPackage {
- /**
- * 返回nativeModule的集合
- */
- override fun createNativeModules(
- reactContext: ReactApplicationContext
- ): MutableList
= listOf(CustomModule(reactContext)).toMutableList() -
- override fun createViewManagers(context: ReactApplicationContext):
- MutableList
>> = mutableListOf() -
- }
然后在MainApplication里写一个reactNativeHost实例化对象,其中在getPackages方法里注册自己刚才写的CustomPackage。
- class MainApplication : Application(), ReactApplication {
-
- override val reactNativeHost: ReactNativeHost =
- object : DefaultReactNativeHost(this) {
- override fun getPackages(): List
= PackageList(this).packages.apply { - add(CustomPackage())
- }
-
- override fun getJSMainModuleName(): String = "index"
-
- override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
-
- override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
- override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
- }
-
- override val reactHost: ReactHost
- get() = getDefaultReactHost(this.applicationContext, reactNativeHost)
-
- override fun onCreate() {
- super.onCreate()
- SoLoader.init(this, false)
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
- // If you opted-in for the New Architecture, we load the native entry point for this app.
- load()
- }
- ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
- }
- }
然后在RN工程目录下新建一个
- import React, {useEffect} from 'react';
- import {Alert, Button, NativeEventEmitter, NativeModules} from 'react-native';
- const {CustomModule} = NativeModules;
-
- const AndroidButtonComponent = () => {
- useEffect(() => {
- const nativeModuleEmitter = new NativeEventEmitter(CustomModule);
- // 监听Android端传递过来的数据
- nativeModuleEmitter.addListener('customEventName', data => {
- // 打印从Android端传递来的参数的key-value
- for (const key in data) {
- console.log('key is ' + key + ' value is ' + data[key]);
- }
- // 这里为了更明显的看到Android端传递过来的参数,将其取出来通过弹窗的形式打印
- Alert.alert(
- '提示',
- data.name,
- [
- {text: '取消', onPress: () => console.log('取消按钮被点击')},
- {text: '确定', onPress: () => console.log('确定按钮被点击')},
- ],
- {cancelable: false},
- );
- });
-
- return () => {
- nativeModuleEmitter.removeAllListeners('customEventName');
- };
- }, []);
-
- // 写button按压下去的一个函数
- const onPress = () => {
- // CustomModule.sendEvent('Tom', 'How are you?');
- // 调用Android端的函数
- CustomModule.sendMessageToReactNative('Android-Message');
- };
-
- return <Button title={'Say Hello'} color={'#841584'} onPress={onPress} />;
- };
-
- export default AndroidButtonComponent;
最后在App.jsx文件当中,将这个组件导出。

可以通过这行命令来启动debug模式
npx react-native start --experimental-debugger
然后输入J可以进入debug的控制台

在这里可以看到打印的日志
最后效果如图所示:
点击这个say hello的button之后,会弹窗提示

file_v3_00bt_1cf1a7b1-90d3-439d-a8ce-08ab5aa5d8ag.MP4
参考: