ReactNative和Android通信

news2024/10/6 8:26:37

初始化一个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

参考:

  • 【笔记】React-Native跟Android交互--简单示例_react-native如何调用安卓-CSDN博客
  • Android与RN的交互与通信_rn android event-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1830176.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java并发自测题

文章目录 一、什么是线程和进程?线程与进程的关系,区别及优缺点&#xff1f;二、为什么要使用多线程呢?三、说说线程的生命周期和状态?四、什么是线程死锁?如何预防和避免线程死锁?五、synchronized 关键字六、并发编程的三个重要特性七、JMM &#xff08;Java Memory Mod…

Android 自定义View

我们所有的试图都是起源于自定义View&#xff0c;包括ViewGroup也是继承于它&#xff0c;可以说它是视图组件之父。 我们可以从它的大致流程来分为四个部分&#xff1a; 构造方法&#xff0c;onMeasure&#xff0c;onLayout&#xff0c;onDraw 构造方法&#xff1a; 它主要有…

Java | Leetcode Java题解之第160题相交链表

题目&#xff1a; 题解&#xff1a; public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA null || headB null) {return null;}ListNode pA headA, pB headB;while (pA ! pB) {pA pA null ? headB : pA.next;pB …

Springmvc接收请求参数

如果你觉得这种限制很麻烦&#xff0c;你可以改为String 因为所有参数在接收的时候原值都是字符串

Mac | 崩溃分析

一、dump分析 1. 导入符号&#xff1a; ./import_pdb.sh libmedia_stream_ext.dylib.dSYM ./import_pdb.sh libowcr.framework.dSYM 2. 分析dump&#xff1a; ./analyze_dump.sh AE59D64F-0E1D-4A18-8DAF-C2C4D22F9FA6.dmp 3. 第 2 步骤 中会输出崩溃模块、崩溃线程及堆栈…

使用 Python 进行测试(5)测试的类型

总结 和我一起唱&#xff01; 冒烟测试&#xff0c;让你快速失败&#xff1b; 回归测试&#xff0c;不打破过去&#xff1b; 健全性检查&#xff0c;保留所拥有&#xff1b; 集成测试&#xff0c;处理副作用&#xff1b; 端到端&#xff0c;永无尽头&#xff01; 回测&#xf…

SwiftUI 6.0(Xcode 16)全新 @Entry 和 @Previewable 宏让开发妙趣横生

概览 如火如荼的 WWDC 2024 已进入第五天&#xff0c;苹果开发平台中众多海量新功能都争先恐后的喷薄欲出。 在这里就让我们从中挑两个轻松有趣的新功能展示给小伙伴们吧&#xff1a;它们分别是 全新的 Entry 和 Previewable 宏。 在本篇博文中&#xff0c;您将学到如下内容&a…

用React编写一个密码组件表单

theme: condensed-night-purple highlight: atelier-cave-light 背景介绍 我们在使用网站或者应用程序的登录界面或创建帐户界面时&#xff0c;往往避免不了需要用户输入密码这一步骤&#xff0c;而用户是否可以选择看见他们输入的密码是十分重要的一项功能。尤其是在当输入的…

Focusky是什么软件

Focusky是一款基于HTML5技术的多媒体演示软件&#xff0c;可以轻松地制作出生动有趣的PPT演示文稿、动画宣传片以及微课。与其他软件相比&#xff0c;Focusky拥有丰富的多媒体资源和动画效果&#xff0c;可以让演示内容更加生动。本文将为您详细介绍Focusky软件的功能&#xff…

awd工具安装

fscan(漏洞扫描) 下载 下载地址: Releases shadow1ng/fscan GitHub 把下载的文件放到指定文件目录里, 在文件的位置打开cmd 输入 fscan64.exe -h 192.168.1.1/24 ok了 接下来说说fscan的使用 使用 1.信息搜集: 存活探测(icmp) 端口扫描 2.爆破功能: 各类服务爆破(…

MongoDB~高可用集群介绍:复制集群(副本集)、分片集群

背景 MongoDB 的集群主要包括副本集&#xff08;Replica Set&#xff09;和分片集群&#xff08;Sharded Cluster&#xff09;两种类型。 副本集 组成&#xff1a;通常由一个主节点&#xff08;Primary&#xff09;和多个从节点&#xff08;Secondary&#xff09;构成。 功…

UniVue更新日志:使用ObservableList优化LoopList/LoopGrid组件的使用

github仓库 稳定版本仓库&#xff1a;https://github.com/Avalon712/UniVue 开发版本仓库&#xff1a;https://github.com/Avalon712/UniVue-Develop UniVue扩展框架-UniVue源生成器仓库&#xff1a;https://github.com/Avalon712/UniVue-SourceGenerator 更新说明 如果大家…

Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…

【java】数学运算考试系统

目录 一、登录界面&#xff1a; 二、管理员界面&#xff1a; 三、学生考试界面&#xff1a; 面向小学低年级学生&#xff0c;随机生成两个整数的加减法算式要求学生解答。要求有用 户登录、注册等 GUI 界面&#xff0c;用户数据存入文件&#xff0c;体现面向对象编程思想。 …

windows11子系统Ubuntu 22.04.4子安装图形化界面

1、windows11家庭版本设置 打开虚拟机安装许可 2、Microsoft Store下载安装ubuntu 我使用的是22.04.4 LTS版本 3、 打开ubuntu 命令窗口 1、打开win11的命令行&#xff0c;在下拉三角下标&#xff0c;打开&#xff0c;可以看到有Ubuntu 的选项&#xff0c;点击即可进入linux命…

【Android面试八股文】你说一说什么是双亲委托机制?为什么需要双亲委托机制?

一、双亲委托机制 1.1 双亲委托机制概述 双亲委托机制是指当一个类加载器收到一个类加载请求时, 该类加载器首先会把请求委派给父类加载器。 如果父类加载器还存在父类加载器,则会一直向上委派,直至最终交由顶层的启动类加载器完成类加载, 每个类加载器都是如此,只有在所…

RIP解决不连续子网问题

#交换设备 RIP解决不连续子网问题 一、不连续子网的概念 相同主网下的子网&#xff0c;被另一个主网分割&#xff0c;例如下面实验拓扑在某公司的网络整改项目中&#xff0c;原先R1 和RS 属于同一主网络 10.0.0.0/8&#xff0c;现被 R2、R3、R4 分离&#xff0c;整网采用了 …

Docker 安装 MySQL5.7 和 MySQL8

文章目录 安装 MySQL5.7拉取镜像前期准备启动容器 安装MySQL8.0拉取镜像查看镜像前期准备启动容器 安装 MySQL5.7 拉取镜像 docker pull mysql:5.7拉下来镜像后 执行 docker images 此时我们已经有这个镜像了。 前期准备 在根目录下创建 app &#xff0c; 在 app 目录下创建…

牛客周赛 Round 47 解题报告 | 珂学家

前言 题解 这真的是牛客周赛&#xff1f; 哭了 欢迎关注 珂朵莉 牛客周赛专栏 珂朵莉 牛客小白月赛专栏 A. 小红的葫芦 签到题 但是写起来有点变扭&#xff0c;方法应该蛮多的 统计分组 有2组一组长度为2&#xff0c;一组长度为3 def check(arr):arr.sort()if arr[0] …

数据结构试题 20-21

真需要就死记吧 二叉树遍历-先序(非递归)【图解代码】_哔哩哔哩_bilibili 解释一下步骤&#xff1a; 一个循环为&#xff1a; 1.取节点 2.放右子树 3.放左子树 每次循环&#xff0c;都要从栈里取出一个节点 先放右子树&#xff0c;再放左子树 那这道题就是&#xff0c;先放1&am…