React Native新架构系列-新架构介绍

从今天起,会陆续更新React Native新架构相关的系列内容,本系列基于React Native 0.73.4版本,从一名Android开发者的视角进行介绍。本系列介绍的内容默认读者对React Native有一定的了解,对基础的开发内容不再赘述。

前言

首先介绍一下React Native新架构的演进时间线,所有的内容来源于React Native团队的博客。

  • 2018年6月,在博客State of React Native 2018中首次提出了React Native团队在重新设计新的架构。

  • 2021年8月,在博客React Native in H2 2021中提出新架构准备开源,并且在Facebook内部,在H1已经迁移了1000多个应用页面到新架构。

  • 2022年3月,在博客An update on the New Architecture Rollout中提出2022年将是新架构正式开源的一年。

  • 2022年3月底,在博客Announcing React Native 0.68中介绍了React Native 0.68版本,这个版本算是新架构的第一个正式发布版本,该版本中提供了新架构的应用模板,开发者可以通过简单的开关控制选择开启新架构。

  • 2023年12月,在博客React Native 0.73 - Debugging Improvements, Stable Symlink Support, and more中介绍了最新的React Native 0.73版本,改进了调试相关能力,同时将Kotlin作为Android侧的默认开发语言,也是当前最新的版本。

快速创建一个新架构的App

在最新的版本(0.73.4)中,创建一个React Native App并开启新架构的方式变的非常简单,只需要执行如下2步即可:

1.卸载旧的cli工具并通过npx创建一个React Native App

# 卸载掉旧的cli工具
npm uninstall -g react-native-cli @react-native-community/cli
# 通过npx创建一个项目
npx react-native@latest init ReactNativeSample

如果你需要在iOS模拟器或者真机上运行,可以安装CocoaPods,这里我主要选择不安装。

image-20240211111236653

顺便提一下,从0.71版本开始,React Native默认支持TypeScript。同时,新架构的App还将Hermes引擎作为默认JS引擎。

2.修改<项目根目录>/android/gradle.properties文件

将该文件中的newArchEnabled字段的值为true,便开启了新架构开关。

需要注意的是,0.73版本中,有以下的环境版本要求:

  • Node.js需要18.x
  • JDK 17

如果要运行该App,可以在命令行执行如下命令,前提是你已经按照官方环境变量设置文档配置好了相关的工具和环境变量。

yarn android

命令执行后会打开2个命令行窗口,一个会编译并安装Android App,另一个会启动一个server,支持代码修改后热更新。运行成功后如下:

image-20240211150502658

如果你想查看Android代码,可以使用AndroidStudio打开项目根目录下的android文件夹即可。

新架构带来的升级

对于新架构,主要的变动在于新的模块系统(即我们在React Native代码中调用原生平台API的能力)和新的渲染系统(即我们在React Native代码中使用原生平台UI组件的能力)。

新的JS引擎Hermes并不是新架构引入的特性,在Android React Native 0.60.4版本或者是iOS React Native 0.64版本上即可选择启动新的Hermes引擎。但直到React Native 0.70版本Hermes才作为默认引擎提供,所以我们也将其作为新架构的一部分进行介绍。

除此之外,在React Native的官方文档中还提到了Codegen,它是一个帮助我们生成大量重复代码的工具,并且在我们编译Android或iOS App时自动进行调用,一般无需刻意关注。

下面我结合官方文档对其分别进行简要的介绍,更加详细的介绍将在后续文章中更新。

JavaScriptInterface(JSI)

JSI是一个轻量级 API,本质上是一个Interface,用于约束C++代码和 JavaScript 引擎之间的操作接口,实现具体操作和引擎之间的解耦,下面介绍的API和组件在C++侧的操作都依赖于此,同时这样也方便我们灵活的切换底层JavaScript引擎。虽然JSI是在新架构稳定版本之前就存在,但由于其在新架构过程中扮演着重要的角色,所以这里也一并进行介绍。

新的模块系统Turbo Native Modules

在旧的React Native架构中,我们调用原生平台API的方式是通过Native Modules,我们调用的各种API能力都是通过其从JS侧调用到原生Android或者iOS侧。

例如下面的调用代码打开一个url:

import { Linking } from 'react-native';Linking.openURL(url).catch(() => {// 跳转失败
});

实际上调用的是NativeModules这个对象上挂载的特定的方法,如下:

NativeModules['IntentAndroid'].openURL

新架构中提出的Turbo Native Modules是Native Module的升级版本,提供了一些额外的好处:

  • 跨平台一致的强类型接口。我们可以使用TypeScript来定义接口类型约束。
  • 允许使用C++编写代码,可以避免跨平台过程中的重复实现(例如:具体API实现可以全部使用C++代码编写来实现跨平台)。
  • 支持延迟加载模块,从而加快应用程序启动速度。
  • 使用JSI(JavaScript Interface)来使API调用通信更加高效。避免了之前的桥通信过程中的json字符串的序列化和反序列化操作。

新老架构在这部分的变动,对上层应用开发没有影响,几乎是无感知的,但对于开发自定义的API能力暴露给React Native侧调用,这部分变化较大,具体内容会在后面的文章中单独介绍。

新的渲染系统Fabric

在旧的React Native架构中,跟渲染系统相关的是UIManager,它负责来将我们在业务代码中写的标签映射到对应的原生组件实现,并管理其更新、移除等行为。一个具体的组件在原生侧都包含一个对应的具体组件以及一个Manager,例如下面使用Text组件:

import React from 'react';
import { Text } from 'react-native';export function SampleText(): React.JSX.Element {return <Text>Sample</Text>;
}

对应到Android侧为RCTText和RCTTextManager这2个类分别负责Text组件的具体实现和管理。

新架构中提出的Fabric Native Component使用Fabric Render进行渲染处理,是传统Native Component的升级版本,提供了一些额外的好处:

  • 跨平台一致的强类型接口。我们可以使用TypeScript来定义组件类型约束。
  • 允许使用C++编写代码,可以避免跨平台过程中的重复实现。
  • 使用JSI(JavaScript Interface)来使组件通信调用更加高效,避免了之前的通信过程中的json字符串的序列化和反序列化操作。
  • 新的渲染系统支持对组件的同步测量和渲染(旧架构中这部分是异步进行的)。

新老架构在这部分的变动,对上层应用开发没有影响,几乎是无感知的,但对于开发自定义的组件暴露给React Native侧调用,这部分变化较大,具体内容会在后面的文章中单独介绍。

新的JS引擎Hermes

Hermes 是一个针对 React Native 优化的开源 JavaScript 引擎。与之前的 JavaScriptCore 相比,使用 Hermes 将缩短启动时间、减少内存使用量并减小应用程序大小。在React Native 0.70版本中,Hermes被作为默认引擎,无需额外配置即可启用它。

当然,你也可以选择在新架构中不启用Hermes,在Android侧,只需要在**<项目根目录>/android/gradle.properties**文件中修改如下一行配置:

hermesEnabled=false

由于有了之前介绍的JSI的存在,这种引擎切换对我们上层是无感知的。

你可以在运行时,通过下面的代码来判断Hermes引擎是否被启用:

const isHermes = () => !!global.HermesInternal;

需要注意的是,也正因为JSI的存在,JSI和Hermes接口之间是有耦合的。因为JSI定义的接口,对应到具体的引擎(例如Hermes)都需要进行实现,所以我们创建的React Native程序都会绑定一个特定版本的Hermes版本。最新的版本中,hermes引擎已经被作为一个aar包发布在maven仓库中。

虽然我们在**<项目根目录>/android/app/build.gradle**中依赖hermes时并没有指定具体aar包的版本,如下图:

image-20240213121453266

但它的版本会在React Native Gradle Plugin中被指定为特定的版本,以保证跟当前的React Native工程版本匹配。

关键代码在**<项目根目录>/node_modules/@react-native/gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt**中,会读取特定的版本配置在依赖解析阶段进行解析配置,如下图:

image-20240213121928136

Codegen

Codegen是一个工具,当我们在开发自定义的Turbo Native Modules或者Fabric Native Component时,需要按照约定生成一些模板代码,就是由它来生成的。一般情况下它是被我们的编译构建工具(例如:Gradle)在编译时自动调用的,所以我们一般无需关心,具体的使用,我们在后续的文章中再进行更加详细的介绍。

总结

本文对React Native的新架构进行了简要的介绍,从创建一个新架构的App,到介绍新架构中涉及到的几个主要的升级,让大家对这部分内容有一个大致的了解,更加详细的内容会在后续的文章中陆续介绍。

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

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

相关文章

【优选算法】——leetcode——438.找到字符串中所有字母异位词

目录 1.题目 2.题目理解 3.算法原理 1.如何快速判断两个字符串是否是异位词 2.解决问题 暴力求解——>滑动窗口哈希表 滑动窗口 利用滑动窗口哈希表解决问题 优化&#xff1a;更新结果的判断条件 4.编程代码 C代码 1.频率统计 2. 双指针 C语言代码 1.字符频率…

MATLAB C++语言编写MEX函数示例:求解本源根

作为一种提升运行效率的手段&#xff0c;MATLAB的MEX函数最初支持C语言编写&#xff0c;从2018a才开始支持基于C11的“现代”C编写MEX&#xff0c;并实现更多现代特性&#xff08;尤其是程序安全性方面&#xff09;。目前&#xff0c;MATLAB官方已不推荐继续用传统C语言编写新的…

【qt小系统】传感器云平台3D散点图(附源码)

摘要&#xff1a;本文主要使用QT5&#xff0c;实现了一个传感器云平台的小示例&#xff0c;模拟的是各类传感器的添加&#xff0c;例如&#xff1a;热成像传感器、温度传感器、超声波传感器&#xff0c;模拟添加完成后&#xff0c;会自动将此传感器的三维坐标增加到3D散点图上&…

Vmware安装openstack

安装虚拟机 创建完成后&#xff0c;点击开启虚拟机 稍等执行成功后 上传压缩包到指定目录。将yoga_patch.tar.gz包上传至/root目录下&#xff0c;将stack3_without_data.tar.gz包使用WinSCP上传至/opt目录下 vim run_yoga.sh #/bin/bash cd /root sudo apt-get update tar -xzv…

添加好友

目录 添加好友的思路&#xff1a; 1.假设A添加B a.如果B在线 b.如果B不在线 添加好友的思路&#xff1a; 1.假设A添加B A给服务端发送要添加B的消息&#xff0c;服务端接受后&#xff0c;先把A添加B的信息存入数据库&#xff0c;再去个人信息表查看B是否在线 a.如果B在线…

「问题解决」jdk高版本导致请求返回对象转换报错

报错&#xff1a;Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException accessible: module java.base does not “opens java.lang” to unn…

UnityShaderUI编辑器扩展

前言&#xff1a; 当我们在制作通用Shader的时候&#xff0c;避免不了许多参数混杂在一起&#xff0c;尽管在材质面板已经使用过Header标签来区分&#xff0c;但是较长的Shader参数就会导致冗余&#xff0c;功能块不够简约明了&#xff0c;如图&#xff1a; 对于Shader制作者来…

FPGA开发——蜂鸣器的控制

一、概述 在项目开发的过程当中&#xff0c;我会通常会需要一个东西就行报警显示&#xff0c;有使用语音报警&#xff0c;信息报警等注入此类的方式&#xff0c;但最为简单使用的还是蜂鸣器的使用&#xff0c;蜂鸣器控制简单&#xff0c;成本低&#xff0c;是最为常用的模块之…

测试面试宝典(三十七)—— 接口测试中的加密参数如何处理?

1&#xff09;先了解接口使用的加密方式(md5、rsa...) 2&#xff09;检查接口测试工具是否支持这种加密方式&#xff0c;如果支持的话&#xff0c;直接使用对应功能就行了(比如Jmeter支持md5)&#xff1b;如果加密方式是公司内部特有的算法&#xff0c;可以在接口测试工具中调…

柯尔莫哥洛夫-阿诺德网络

柯尔莫哥洛夫-阿诺德网络&#xff08;Kolmogorov-Arnold Network&#xff0c;简称KAN&#xff09;是一个理论框架&#xff0c;主要用于描述高维函数如何通过一组低维函数的组合来近似表示。这个理论的基础源自安德烈柯尔莫哥洛夫和弗拉基米尔阿诺德在函数逼近理论中的工作&…

NSSRound#4 Team

[NSSRound#4 SWPU]1zweb 考察&#xff1a;phar的反序列化 1.打开环境&#xff0c;审计代码 1.非预期解 直接用file伪协议读取flag,或直接读取flag file:///flag /flag 2.正常解法 用读取文件读取index.php,upload.php的源码 index.php: <?php class LoveNss{publi…

3. Docker的数据管理与持久化

在Docker容器化应用中&#xff0c;数据的持久化和管理是一个关键问题。容器的生命周期短暂&#xff0c;容器的停止和删除会导致数据丢失。因此&#xff0c;了解Docker的数据卷&#xff08;Volumes&#xff09;和挂载&#xff08;Mounts&#xff09;的管理方式&#xff0c;对保障…

环境搭建-Docker搭建ClickHouse

Docker搭建ClickHouse 一、前言二、ClickHouse安装2.1 拉取镜像运行ClickHouse服务 三、测试安装3.1 进入clickhouse容器3.2 命令补充说明 四、测试连接五、设置CK的用户名密码 一、前言 本文使用的Docker使用Windows搭建&#xff0c;Linux版本的搭建方式一样。 Windows系统搭…

Data Race: 并发编程中的数据竞争问题

Data Race: 并发编程中的数据竞争问题 &#x1f50d; &#x1f680; Data Race: 并发编程中的数据竞争问题 &#x1f50d;摘要引言正文内容一、什么是数据竞争&#xff1f; &#x1f914;1.1 数据竞争的定义1.2 数据竞争的特征 二、数据竞争的原因和影响 &#x1f6a8;2.1 原因…

Redis学习笔记——第18章 发布与订阅

第18章 发布与订阅 18.1 频道的订阅与退订 订阅关系保存在字典中&#xff0c;Key为频道&#xff0c;value为订阅该频道的客户端链表 18.2 模式的订阅与退订 可以使用通配符&#xff0c;如果订阅了news.*类型的频道&#xff0c;则会将news.*保存为一个Key&#xff0c;value为…

SpringBoot2整合Kafka

引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.springframework.kafka</groupId><artifactId>s…

小主机SSD固态硬盘选购攻略,希捷酷鱼 530 SSD固态硬盘表现优秀【附系统无损迁移教程】

小主机SSD固态硬盘选购攻略&#xff0c;希捷酷鱼 530 SSD固态硬盘表现优秀【附系统无损迁移教程】 哈喽小伙伴们好&#xff0c;我是Stark-C~ 这几年随着以零刻为首的小主机市场的兴起&#xff0c;小主机相关的配置周边需求也是越来越大&#xff0c;就比如说SSD固态硬盘就是其…

《Windows API每日一练》22.3 SHE异常

本节我们将讲述单线程到多线程的演进过程&#xff0c;以及进程与线程的区别。 本节必须掌握的知识点&#xff1a; SHE异常 第170练&#xff1a;SEH异常处理程序 第171练&#xff1a;setjmp和longjmp进行异常捕获与处理 22.3.1 SHE异常 在C语言中&#xff0c;Windows平台提供…

定制数据流:在Mojo模型中打造个性化数据预处理

定制数据流&#xff1a;在Mojo模型中打造个性化数据预处理 数据预处理是机器学习工作流程中的关键步骤&#xff0c;它直接影响到模型的性能和训练效率。Mojo模型&#xff0c;作为一个先进的机器学习框架&#xff0c;提供了强大的扩展性来支持自定义数据预处理。本文将深入探讨…