推荐用于学习RN原生模块开发的开源库—react-native-ble-manager

如题RN的原生模块/Native Modules的开发是一项很重要的技能,但RN官网的示例又比较简单,然后最近我接触与使用、还有阅读了react-native-ble-manager的部份源码,发现里边完全包含了一个Native Modules所涉及的知识点/技术点,故特推荐给大家,共同学习与交流
react-native-ble-manager目前有1.8K的star
在这里插入图片描述
如下所示,react-native-ble-manager是RN开发环境下蓝牙低功耗库,用于RN应用下的低功耗蓝牙通讯功能的编程
在这里插入图片描述

react-native-ble-manager的代码结构

代码量不多,如果有原生平台下的蓝牙开发/API有基础的话,阅读起来会更容易些
在这里插入图片描述

于分层思想理解原生模块

如 Android 原生模块 的指引内容如下
在这里插入图片描述
在RN项目开发过程中,大多数情况下我的业务逻辑、基础库等基本是用JS/TS代码去组织与编写的,但实际我们用的大部份RN第三方面都是一个个原生模块形态的SDK。我们在项目中添加一个原生模块相对于构建一个原生模块形态的SDK要简单些,SDK的话还需要处理构建打包。如下是我于分层架构的思想对原生模块的理解。原生模块顾名思义就是需要依赖与使用到原生平台的API或功能的模块,该模块对于上层业务来说是一个普通的JS模块,故原生模块是实际上是存在两大子模块,一个是用JS模块,另一个是平台层模块,JS模块直接服务上层JS业务模块的,即称之为接口模块,然后平台层模块是内部的实现模块,使用平台层语言直接使用平台层的功能特性。那原生模块的JS代码跟平台层代码是如何通讯/交互的呢?这种场景是需要引入一个胶水层来处理,但我们不需要想Android jni开发那样去花大量的精力去构建胶水层,原因RN框架已经提供了这个胶水层的功能,所以我就按RN 原生模块开发的规范来构建与编写相关的代码就行了
在这里插入图片描述

从角色视角理解原生模块

在这里插入图片描述

通过react-native-ble-manager去看原生模块

介绍Android平台为主

主要文件

在这里插入图片描述

主要类图

在这里插入图片描述

从scan接口看JS与原生的交互

从JS的scan跟到Java层的scan接口,可以大概了解参数类型的转化,还有JS调用native方法后面回调处理,使用callback的方式
在这里插入图片描述

//js代码调scan,RN框架会帮忙代到并调到对应native层的scan方法,同时调用该方法时会做js数据类型到java数据类型的转换
 bleManager.scan(
        serviceUUIDs,
        seconds,
        allowDuplicates,
        scanningOptions,
        //下面这个就是一个js function对应到java就是一个callback类型
        (error: string | null) => {
          if (error) {
            reject(error);
          } else {
            fulfill();
          }
        }
      );
    });
//如下是java代码,BleManager.java类中scan方法
 @ReactMethod
    public void scan(ReadableArray serviceUUIDs, final int scanSeconds, boolean allowDuplicates, ReadableMap options,
                     Callback callback) {
        Log.d(LOG_TAG, "scan");
        if (getBluetoothAdapter() == null) {
            Log.d(LOG_TAG, "No bluetooth support");
            callback.invoke("No bluetooth support");
            return;
        }
        if (!getBluetoothAdapter().isEnabled()) {
            return;
        }

        synchronized (peripherals) {
            for (Iterator<Map.Entry<String, Peripheral>> iterator = peripherals.entrySet().iterator(); iterator
                    .hasNext(); ) {
                Map.Entry<String, Peripheral> entry = iterator.next();
                if (!(entry.getValue().isConnected() || entry.getValue().isConnecting())) {
                    iterator.remove();
                }
            }
        }

        if (scanManager != null)
            scanManager.scan(serviceUUIDs, scanSeconds, options, callback);
    }

注意观察上面的JS代码中调scan方法的参数,然后再对着下面JS数据类型跟JAVA数据类型的关系去看代码。
特别要重点体会callback跟function的映射,因为callback是native方法回调js时经常用到的方式
在这里插入图片描述
再来看一下native主动向js交互的case,目前是采用EventEmitter机制来交互的。即JS需要注册事件,然后native端发送对应的事件即可。这个事件从Jvmruntime到Js runtime的胶水层RN已经帮忙我们实现了,调用对应的emmiter组件即可
如下是JS端注册事件的代码

const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);
//注删事件ID是一个String,如下面的 BleManagerDiscoverPeripheral,然后我们去native端的代码去搜索BleManagerDiscoverPeripheral
....
 const listeners = [
      bleManagerEmitter.addListener(
        'BleManagerDiscoverPeripheral',
        handleDiscoverPeripheral,
      ),
      bleManagerEmitter.addListener('BleManagerStopScan', handleStopScan),
      bleManagerEmitter.addListener(
        'BleManagerDisconnectPeripheral',
        handleDisconnectedPeripheral,
      ),
      bleManagerEmitter.addListener(
        'BleManagerDidUpdateValueForCharacteristic',
        handleUpdateValueForCharacteristic,
      ),
    ];

//通过BleManagerDiscoverPeripheral看到native的有这样的代码, 
private void onDiscoveredPeripheral(final ScanResult result) {
        .....

        WritableMap map = peripheral.asWritableMap();
        bleManager.sendEvent("BleManagerDiscoverPeripheral", map);
    }

 public void sendEvent(String eventName, @Nullable WritableMap params) {
      getReactApplicationContext().getJSModule(RCTNativeAppEventEmitter.class).emit(eventName, params);
 }

总结

1、native端用RCTNativeAppEventEmitter来发送事件,js端用NativeEventEmitter来注册事件,即达到下层可以主动向上层通讯
2、callback经常用来作native方法的调用结果返回到JS runtime的常规操作,即方法调用与结果返回,一来一回的双向操作。

建议

1、用webstorm打开整个目标,方便阅读js/ts代码
2、用AS打开Android目录,方便阅读java代码
3、用xcode或appcode打开ios目录,方便阅读ios代码

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java商城系统和php商城系统对比

java商城系统和php商城系统是两种常见的电子商务平台&#xff0c;它们都具有一定的优势和劣势。那么&#xff0c;java商城系统和php商城系统又有哪些差异呢&#xff1f; 一、开发难度 Java商城系统和PHP商城系统在开发难度方面存在一定的差异。Java商城系统需要使用Java语言进…

jenkins执行jmeter时,报Begin size 1 is not equal to fixed size 5

jenkins执行jmeter脚本的时候一直提示如下错误&#xff1a; Tidying up ... Fri Jul 28 17:03:53 CST 2023 (1690535033178) Error generating the report: org.apache.jmeter.report.dashboard.GenerationException: Error while processing samples: Consumer failed wi…

WEB:wife_wife

背景知识 JavaScript原型链污染 题目 先尝试一下&#xff0c;注册了管理员账号 这里不知道邀请码&#xff0c;所以没有勾选 答案不正确 这里借鉴其他大佬的思路 查看源代码才知道&#xff0c;后端没有数据库&#xff0c;所以sql注入是不可能的 // post请求的路径 app.pos…

qemu搭建arm环境以及文件共享

几乎完全参照该文章 使用QEMU搭建ARM64实验环境 - 简书 ubuntu 14.04&#xff0c;linux3.16&#xff0c; busybox-1.31.0 arm-linux-gnueabi-gcc -v linux3.16以及busybox下载安装可参考链接 Ubuntu14.04安装qemu&#xff0c;运行linux-3.16gdb调试_qemu 安装 ubuntu 14_这个我…

Redis—相关背景

Redis—相关背景 &#x1f50e;Redis—特性In-memory data structures—在内存中存储数据Programmability—可编程性Extensibility—可扩展性Persistence—持久化Clustering—集群High availability—高可用 &#x1f50e;Redis 为什么快&#x1f50e;Redis 的使用场景Real-tim…

性能测试Ⅲ

JMeter里面使用后端监听器&#xff0c;结合influxdb的时序数据库以及grafana可以打造性能测试的平台 后端监听器&#xff1a;把JMeter执行过程中的数据写到influxDB的时序数据库 influxD&#xff1a;时序数据库&#xff0c;用来存储JMeter发送请求的数据 Grafana &#xff1a;从…

vue3+ts+elementui-plus二次封装树形表格

复制粘贴即可&#xff1a; 一、定义table组件 <template><div classmain><div><el-table ref"multipleTableRef" :height"height" :default-expand-all"isExpend" :data"treeTableData"style"width: 100%…

CAN总线开发必看! 如何使用CANlib检测CAN帧溢出情况? Kvaser三招帮你轻松解决

从1980年代&#xff0c;Kvaser就开始CAN产品的研发&#xff0c;在相关产品开发领域有近40多年的经验&#xff0c;对CAN和相关总线技术有着非常深入的研究。广州智维电子科技是KVASER的中国引进者&#xff0c;我们会不定期分享一些有趣的发现和特定情况的技术处理。 在开发严重…

600 条最强 Linux 命令总结

今天&#xff0c;带来一篇 Linux 命令总结的非常全的文章&#xff0c;也是我们平时工作中使用率非常高的操作命令&#xff0c;命令有点多&#xff0c;建议小伙伴们可以先收藏后阅读。 1. 基本命令 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 dmidecode -…

【LeetCode】102.二叉树的层序遍历

题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&#xff1a; …

MySQL基础(四)数据库备份

目录 前言 一、概述 1.数据备份的重要性 2.造成数据丢失的原因 二、备份类型 &#xff08;一&#xff09;、物理与逻辑角度 1.物理备份 2.逻辑备份 &#xff08;二&#xff09;、数据库备份策略角度 1.完整备份 2.增量备份 三、常见的备份方法 四、备份&#xff08…

自动驾驶技术架构

自动驾驶技术架构 自动驾驶技术架构 自动驾驶关键技术 自动驾驶汽车技术架构较为复杂&#xff0c;涉及了多领域的交叉互容&#xff0c;例如汽车、交通、通信等&#xff0c;基于自动驾驶相关的软硬件、辅助开发工具、行业标准等各方面关键问题&#xff0c;自动驾驶汽车关键技术…

教育机构视频播放时观看行为分析有哪些应用?

教育机构视频播放时观看行为分析有哪些应用&#xff1f; 观看行为分析 观看行为分析是指我们平台基于视频大数据分析&#xff0c;能够以秒为粒度展示观众如何观看您的视频。 视频观看热力图是单次观看行为的图形化表示&#xff0c;我们平台云点播视频的每一次播放&#xff0…

【一天三道算法题】代码随想录——Day14

一. 有效的括号 题目链接&#xff1a;力扣 思路&#xff1a;无非三种情况&#xff1a; 1. 左侧括号多&#xff0c;右侧少 2. 左右侧一样多&#xff0c;该字符串属于有小括号字符串 3. 右侧括号多&#xff0c;左侧少 那么说白了就是要比较左右括号的数量&#xff0c;谁多&…

行业追踪,2023-07-28

自动复盘 2023-07-28 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

图片转pdf手机版免费?这几款转换软件看看

图片转pdf手机版免费&#xff1f;将图片转换成PDF文件可以带来很多好处。首先&#xff0c;PDF文件可以更好地保护你的图片。相对于图片文件&#xff0c;PDF文件更难以编辑和改变&#xff0c;因此更适合用于存储重要的图片。其次&#xff0c;将多张图片合并成一个PDF文件可以更好…

《面试1v1》Kafka与传统消息系统区别

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

前端Vue入门-day04-用vue实现组件通信

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 组件的三大组成部分 注意点说明 组件的样式冲突 scoped data 是一个函数 组件通信 什么是组件通信 不…

手撕顺序表

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…

Redis原理篇(二)

三、Redis网络模型 3.1 用户空间和内核态空间 服务器大多都采用Linux系统&#xff0c;这里我们以Linux为例来讲解: ubuntu和Centos 都是Linux的发行版&#xff0c;发行版可以看成对linux包了一层壳&#xff0c;任何Linux发行版&#xff0c;其系统内核都是Linux。我们的应用都…