ReactNative和Android通信

发布于:2024-06-17 ⋅ 阅读:(39) ⋅ 点赞:(0)

初始化一个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<NativeModule> = listOf(CustomModule(reactContext)).toMutableList()

    override fun createViewManagers(context: ReactApplicationContext):
            MutableList<ViewManager<View, ReactShadowNode<*>>> = mutableListOf()

}

然后在MainApplication里写一个reactNativeHost实例化对象,其中在getPackages方法里注册自己刚才写的CustomPackage。

class MainApplication : Application(), ReactApplication {

  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> = 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

参考:


网站公告

今日签到

点亮在社区的每一天
去签到