• ReactNative和Android通信


    初始化一个RN项目以后,接下来想要让Android与React Native通信

    写一个继承自ReactContextBaseJavaModule类的子类,重写getName方法

    1. package com.awesomeproject
    2. import android.util.Log
    3. import android.widget.Toast
    4. import com.facebook.react.bridge.Arguments
    5. import com.facebook.react.bridge.ReactApplicationContext
    6. import com.facebook.react.bridge.ReactContextBaseJavaModule
    7. import com.facebook.react.bridge.ReactMethod
    8. import com.facebook.react.modules.core.DeviceEventManagerModule
    9. class CustomModule(reactContext: ReactApplicationContext?) :
    10. ReactContextBaseJavaModule(reactContext) {
    11. companion object {
    12. const val TAG = "CustomModule"
    13. }
    14. /**
    15. * 返回注册module的名字
    16. */
    17. override fun getName(): String {
    18. return "CustomModule"
    19. }
    20. @ReactMethod
    21. fun sendEvent(name: String?, msg: String?) {
    22. if (name != null && msg != null) {
    23. Toast.makeText(
    24. reactApplicationContext,
    25. "the name is $name: the msg is $msg",
    26. Toast.LENGTH_SHORT
    27. ).show()
    28. }
    29. }
    30. @ReactMethod
    31. fun sendMessageToReactNative(msg: String?) {
    32. val params = Arguments.createMap()
    33. Log.i(TAG, "msg is $msg")
    34. params.putString("name", msg)
    35. // 传递给js端参数
    36. reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
    37. .emit("customEventName", params)
    38. }
    39. }

    重写一个继承自ReactPackage类的子类,重写createNativeModules和createViewManagers方法

    1. package com.awesomeproject
    2. import android.view.View
    3. import com.facebook.react.ReactPackage
    4. import com.facebook.react.bridge.NativeModule
    5. import com.facebook.react.bridge.ReactApplicationContext
    6. import com.facebook.react.uimanager.ReactShadowNode
    7. import com.facebook.react.uimanager.ViewManager
    8. class CustomPackage : ReactPackage {
    9. /**
    10. * 返回nativeModule的集合
    11. */
    12. override fun createNativeModules(
    13. reactContext: ReactApplicationContext
    14. ): MutableList = listOf(CustomModule(reactContext)).toMutableList()
    15. override fun createViewManagers(context: ReactApplicationContext):
    16. MutableList>> = mutableListOf()
    17. }

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

    1. class MainApplication : Application(), ReactApplication {
    2. override val reactNativeHost: ReactNativeHost =
    3. object : DefaultReactNativeHost(this) {
    4. override fun getPackages(): List = PackageList(this).packages.apply {
    5. add(CustomPackage())
    6. }
    7. override fun getJSMainModuleName(): String = "index"
    8. override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
    9. override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
    10. override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
    11. }
    12. override val reactHost: ReactHost
    13. get() = getDefaultReactHost(this.applicationContext, reactNativeHost)
    14. override fun onCreate() {
    15. super.onCreate()
    16. SoLoader.init(this, false)
    17. if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
    18. // If you opted-in for the New Architecture, we load the native entry point for this app.
    19. load()
    20. }
    21. ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
    22. }
    23. }

    然后在RN工程目录下新建一个

    1. import React, {useEffect} from 'react';
    2. import {Alert, Button, NativeEventEmitter, NativeModules} from 'react-native';
    3. const {CustomModule} = NativeModules;
    4. const AndroidButtonComponent = () => {
    5. useEffect(() => {
    6. const nativeModuleEmitter = new NativeEventEmitter(CustomModule);
    7. // 监听Android端传递过来的数据
    8. nativeModuleEmitter.addListener('customEventName', data => {
    9. // 打印从Android端传递来的参数的key-value
    10. for (const key in data) {
    11. console.log('key is ' + key + ' value is ' + data[key]);
    12. }
    13. // 这里为了更明显的看到Android端传递过来的参数,将其取出来通过弹窗的形式打印
    14. Alert.alert(
    15. '提示',
    16. data.name,
    17. [
    18. {text: '取消', onPress: () => console.log('取消按钮被点击')},
    19. {text: '确定', onPress: () => console.log('确定按钮被点击')},
    20. ],
    21. {cancelable: false},
    22. );
    23. });
    24. return () => {
    25. nativeModuleEmitter.removeAllListeners('customEventName');
    26. };
    27. }, []);
    28. // 写button按压下去的一个函数
    29. const onPress = () => {
    30. // CustomModule.sendEvent('Tom', 'How are you?');
    31. // 调用Android端的函数
    32. CustomModule.sendMessageToReactNative('Android-Message');
    33. };
    34. return <Button title={'Say Hello'} color={'#841584'} onPress={onPress} />;
    35. };
    36. 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

    参考:

  • 相关阅读:
    六、vim编辑器的使用
    开发盲盒商城的意义
    Java中SnowFlake 雪花算法生成全局唯一id中的问题,时间不连续全为偶数解决
    Maven插件mybatis-generator,如何让生成的PO类的field上有对应表字段的注释
    【开源】JAVA+Vue.js实现医院门诊预约挂号系统
    【狂神说Java】redis
    2022 SIGIR 面向情感分析的方面级特征提取与增强网络
    进程与线程
    Redis实现布隆过滤器(上)
    ipad手写笔有必要买原装吗?第三方性价比高的手写笔推荐
  • 原文地址:https://blog.csdn.net/qq_41688840/article/details/139728712