📜  React Native 中的桥梁是什么?

📅  最后修改于: 2022-05-13 01:56:20.178000             🧑  作者: Mango

React Native 中的桥梁是什么?

React Native 应用程序包含两个方面,如下所示。

  1. JavaScript 方面
  2. 原生的一面

Native Side 对于 Android 应该是Java或 Kotlin,对于 iOS 应该是 Swift 或 Objective-C。

React Native 流行的一个重要原因是可以在 JavaScript 代码和 Native 语言之间架起一座桥梁。 React Native 的开发方式可以让我们在 JavaScript 代码和 Native 语言之间架起一座桥梁。 React Native 中的 Bridge 允许 JavaScript 代码和 Native 代码相互交互。如果没有 React Native 中的桥梁,本机代码绝对无法将任何信息传递给 JavaScript 代码,反之亦然。

React Native 中对 Bridge 的需求:假设我们需要重新利用几个现有的Java库,而无需在 JavaScript 中再次实现它。因此,我们可以使用 Native Bridge 在我们的 React Native 应用程序中重新利用它。有时,要构建生产级别的应用程序,我们很可能需要使用 Native Bridge。

桥接的工作:当我们点击我们的应用程序图标打开我们的应用程序时,操作系统会设计主线程(又名 UI 线程)并将这个线程分配给我们的应用程序。该主线程创建 JavaScript 线程和影子线程(也称为影子树)。影子线程的任务是计算 JavaScript 端描述的布局,并将该细节重定向到 Native 端。视图在 JavaScript 中设置,在影子树中计算,并重定向到 UI 线程。

调度数据:现在我们知道布局在开始时是如何描述的,但是在应用程序开始运行之后会发生什么?当我们需要削弱按钮时会发生什么?此详细信息是否通过网桥发送?

为了削弱按钮,我们可以在 JavaScript 端设置一个功能,该功能将像序列化的 JSON 对象一样在桥上方重定向。本机视图的改进同时分组,并在事件循环的所有迭代结束时重定向到本机端。

除了传递属性,我们还可以传递一个函数,该函数将运行 JavaScript 代码作为对本机端的多个事件的反应(例如按下按钮)。我们注意到 JavaScript 中的这个回调,它被序列化并重定向到本机端。当我们按下按钮时,原生事件被重定向到 JavaScript 域并执行回调。现在,我们还可以直接将事件从本机端重定向到 JavaScript 端,而无需使用回调。问题是,如果我们在本机端开始这种交互,那么我们不知道谁在关注 JavaScript 端,这可能会激活不需要的步骤,并且会使我们的代码难以调试。使用 JS 端的回调更有意义,除非有明确的理由不这样做。

执行:大多数情况下,所有事情都平稳地通过,但有时就像一座原始的桥梁一样,它会遇到交通堵塞。当有一个很大的项目目录并且我们开始快速滚动时,我们可能会在传送其余项目之前识别出一个空白屏幕。这是因为 onScroll 原生事件被重定向到 JavaScript 线程,JavaScript 线程将新的布局细节传输到影子树,影子树计算布局并重定向到原生端。在快速滚动的同时,我们收集了这些导致桥上交通堵塞的事件。我们可以尝试通过预先计算布局来避免这种情况,以便几次过桥。在执行复杂的动画时,我们会遇到类似的执行问题。

现在让我们深入探索并了解 React Native 是如何在后台运行的,这将有助于我们理解 JavaScript 到 Native 代码的编译以及整个过程的工作。了解整个过程是如何工作的很重要,因此有时如果您遇到性能问题,那么您就会认识到问题的根源。

信息流:正如我们所讨论的,为 React Native 提供动力的 React 想法是其中之一,即 UI 是数据的函数。您可以转换条件,React 会通知要更新的内容。现在让我们假设细节如何与通常的 React 应用程序一起流动。探索下面给出的图表:

上图说明:

  1. 我们有一个 React 部分,其中包含三个子部分的详细信息。
  2. 匿名发生的是生成了一个虚拟 DOM 树,构成了这些部分层次结构。
  3. 当父部分的条件更新时,React 会注意到如何对子部分进行详细说明。
  4. 由于 children 主要是 UI 的描述,React 认识到如何对 Browser DOM 更新进行分组并实现它们。

现在让我们分离 Browser DOM 并假设 React Native 不是对 Browser DOM 更新进行分组,而是通过调用 Native 模块来做同样的事情。因此,Native 模块的处理细节可以通过两种方式完成,如下所示:

  1. 共享可变数据
  2. 在 JavaScript 和 Native 模块之间交换的可序列化消息

React Native 使用第二种方法,即在 JavaScript 和 Native 模块之间交换 Serializable 消息。它不是在可共享对象上改变数据,而是将异步序列化的分组消息发送到 React Native 的桥。 React Native 中的 Bridge 是允许 JavaScript 代码和 Native 代码相互交互的层。

架构:下图解释了 React Native 架构的结构:

反应原生架构

上图中说明了三层:

  1. JavaScript
  2. 本国的

React Native 中的 Bridge 是允许 JavaScript 和 Native 模块相互交互的层,主要是一个载体层,将非并行的按时间顺序分组的反馈消息从 JavaScript 传递到 Native 模块。在上面给出的图片中,Native 层显示在最后,因为该层离设备本身最近。

当事件在 Native 层实现时,它可能是计时器、触摸或网络请求,主要是与设备 Native 模块相关联的任何事件。它的数据被组装起来,这些数据作为序列化消息发送到 React Native Bridge。之后,Bridge 将该消息传递给 JavaScript 层。

JavaScript 层是一个事件循环。在 React Native Bridge 将 Serialized 有效负载处理为 JavaScript 之后,事件将被处理并且应用程序逻辑变为活动状态。

线程模型:现在,在我们上面讨论的所有事情之后,重要的是要认识到上面讨论的所有事情都是在三个主要线程上完成的:

  1. UI(应用程序的主线程)
  2. 原生模块
  3. JavaScript 运行时

让我们了解上述每个线程:

  • UI(应用程序的主线程):它是发生原生级别感知的 Native 线程,是我们选择的平台(如 iOS 或 Android)执行绘图、样式和测量的地方。

  • 机模块:如果应用程序访问任何本机 API,则访问是在不同的本机模块线程上完成的。例如,如果访问相机、位置、照片和任何其他 Native API,则通常还会在此线程上完成排列和指示。

  • JavaScript 运行时:它是每个 JavaScript 应用程序代码将运行的线程。毕竟它是基于 JavaScript 事件循环的,所以它比 UI 线程更稳定。因此,当在执行许多 UI 更改的应用程序中完成复杂的计算时,这些可能会导致性能下降。