React Native 原理

Flying
2018-03-22 / 0 评论 / 133 阅读 / 正在检测是否收录...

React Native 是一个用于构建基于 JavaScript 和 React 的移动应用程序的开源框架。它允许开发人员使用类似于 React 的语法和组件模型来构建原生 iOS 和 Android 应用程序。React Native 可以通过一些平台特定的代码来访问设备功能,如相机、GPS 和通知等。它还提供了一些预构建的组件和工具,以帮助开发人员快速构建高质量的应用程序。

react.svg

发展历史

  1. 2013 年,Facebook 发布了 React,这是一个用于构建用户界面的 JavaScript 库。
  2. 2015 年,Facebook 在 React 的基础上发布了 React Native,这是一个用于构建原生移动应用程序的框架。
  3. 2016 年,React Native 开发团队发布了 0.30 版本,这个版本引入了 Android 支持。
  4. 2017 年,React Native 发布了 0.44 版本,这个版本引入了新的调试工具、改进了性能和稳定性,并增加了一些新功能。
  5. 2018 年,React Native 开发团队发布了 0.56 版本,这个版本引入了新的架构和一些新功能,如 FlatList 和 SectionList。

目前为止,App 大体历了桌面应用、Web 应用、原生应用(Native App)、混合应用(Hybrid App)、React Native 应用这样一个发展演化。下面我们来看看它们的区别联系。

原生 / 混合应用的联系区别

原生应用:原生应用是指专门为特定移动平台开发的应用程序,它可以最大程度地利用特定平台的设备功能。

混合应用:混合应用是使用 HTML、CSS 和 JavaScript 等 Web 技术,在原生容器中运行的应用程序,可以跨多个移动平台,但是在性能上较原生应用有所下降。

React Native 应用:React Native 是一种使用 JavaScript 和 React 库编写跨平台应用程序的框架,可以在 iOS 和 Android 两个平台上运行,性能上比混合应用有所提高。

React Native 的优缺点

React Native 使用 React 来创建 Android 和 iOS 的原生应用。React Native 将原生开发的最佳部分与 React 相结合, 致力于成为构建用户界面的顶尖 JavaScript 框架。

优点

  1. 跨平台:React Native 可以同时开发 iOS 和 Android 应用程序,减少了开发人员的工作量和时间成本。
  2. 高效性:React Native 使用了一些优化技术,如虚拟 DOM 和异步渲染,可以提高应用程序的性能和响应速度。
  3. 热更新:React Native 支持热更新,可以在不重新编译应用程序的情况下更新代码和界面。
  4. 社区支持:React Native 有一个庞大的社区,可以提供大量的文档、教程和开源组件,方便开发人员使用和学习。
  5. 可扩展性:React Native 可以与其他技术和框架集成,如 Redux、MobX 和 GraphQL,可以扩展应用程序的功能和性能。

缺点

  1. 学习曲线:React Native 使用了一些新的概念和技术,需要一定的学习曲线,对于新手来说可能会有一定的难度。
  2. 原生支持:虽然 React Native 可以访问一些原生功能,但是有些功能可能需要使用原生代码来实现,这需要开发人员具备一定的原生开发技能。
  3. 性能问题:虽然 React Native 可以提高应用程序的性能,但是在某些情况下,如处理大量数据或复杂动画时,可能会出现性能问题。
  4. 第三方库兼容性:由于 React Native 是一个相对较新的技术,一些第三方库可能不兼容或存在 bug,需要开发人员自行解决。
  5. 调试问题:由于 React Native 使用了 JavaScript,调试可能会比原生应用程序更困难。

使用场景

  1. 无线应用:React Native 可以开发跨平台的无线应用,可以同时发布到 iOS 和 Android 平台。
  2. 游戏:React Native 也可以用于开发游戏,它可以提供良好的游戏体验,可以让游戏开发变得更加容易。
  3. 数据可视化:React Native 可以用于创建可视化数据,从而让数据变得更加可视化,更加容易理解。
  4. 企业应用:React Native 可以用于企业级应用的开发,它可以实现多平台的企业应用,让企业应用的开发更加容易。
  5. 社交应用:React Native 可以用于开发多平台的社交应用,它可以让社交应用的开发变得更加容易。

实现原理

React Native 将原生组件和 JavaScript 线程结合起来,使用虚拟 DOM 和桥接层来连接它们,并提供了一些核心组件和布局引擎来简化应用程序的开发。

  1. 原生组件:React Native 使用原生组件来渲染应用程序界面,这些组件是由原生平台提供的,如 iOS 上的 UIView 和 Android 上的 ViewGroup。
  2. JavaScript 线程:React Native 使用 JavaScript 线程来处理应用程序的逻辑和渲染,这个线程运行在一个单独的 JavaScript 引擎中,如 iOS 上的 JavaScriptCore 和 Android 上的 V8。
  3. 虚拟 DOM:React Native 使用虚拟 DOM 来描述应用程序界面,这个虚拟 DOM 是一个 JavaScript 对象树,它描述了应用程序界面的结构和属性。
  4. 桥接层:React Native 使用桥接层来连接原生组件和 JavaScript 线程,这个桥接层允许 JavaScript 线程调用原生组件的方法,并将原生组件的事件传递给 JavaScript 线程。
  5. 核心组件:React Native 提供了一些核心组件,如 View、Text 和 Image,这些组件是由原生组件构建的,但是它们的属性和方法是由 JavaScript 线程控制的。
  6. 布局引擎:React Native 使用 Flexbox 布局引擎来处理应用程序界面的布局,这个布局引擎是由 JavaScript 线程控制的。

React Native Bridge

React Native 使用了一种叫做 Bridge 的机制来实现 Native 和 JavaScript 之间的通信。Bridge 是 React Native 的核心部分,它是连接 JavaScript 和 Native 代码之间的桥梁,负责将 JavaScript 的代码运行在 JavaScript 引擎中,并将 UI 控件通过 Bridge 映射到原生的 UI 组件上。

具体来说,当 React Native 应用程序运行时,它会创建一个 JavaScript 引擎实例,将 JavaScript 代码加载到该引擎中,并且将 JavaScript 代码中定义的组件映射到 Native 组件上。当 JavaScript 代码需要调用 Native 代码时,它会通过 Bridge 将调用信息传递给 Native 代码,Native 代码再执行相应的操作,并将结果通过 Bridge 返回给 JavaScript 代码。

通过 React Native Bridge,开发者可以使用原生代码来实现一些高性能的功能,比如图片处理、视频播放、地图显示等。同时,也可以在原生代码中使用 React Native 的组件和 API,从而提高开发效率和代码复用率。

React Native 如何调用 Android 原生模块

React Native 可以通过 Native Modules 的方式调用 Android 原生模块。Native Modules 是 React Native 提供的一种机制,可以让 JavaScript 代码调用原生模块的方法。

具体步骤如下:

  1. 创建一个 Java 类,实现 ReactContextBaseJavaModule 接口,并在该类中定义需要暴露给 JavaScript 的方法。
public class MyModule extends ReactContextBaseJavaModule {
  public MyModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName() {
    return "MyModule";
  }

  @ReactMethod
  public void showToast(String message) {
    Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_SHORT).show();
  }
}
  1. 在 MainApplication.java 中注册该模块。
@Override
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
    new MainReactPackage(),
    new MyPackage()
  );
}

private class MyPackage implements ReactPackage {
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new MyModule(reactContext));
    return modules;
  }

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }
}
  1. 在 JavaScript 中调用该模块的方法。
import { NativeModules } from 'react-native';

NativeModules.MyModule.showToast('Hello, world!');

在上述代码中,我们首先通过 import 引入了 NativeModules 对象,然后通过该对象调用 MyModule 模块的 showToast 方法。

需要注意的是,模块名 MyModule 必须与 getName 方法返回的字符串相同,否则会导致调用失败。

Android 原生模块如何调用 React Native

要在 Android 中调用 React Native 方法,需要执行以下步骤:

  1. 在 React Native 项目中创建一个 Native Module,该模块将包含要在 Android 中调用的方法。
  2. 在 Android 项目中添加 React Native 依赖项,并将 React Native 模块添加到 Android 项目中。
  3. 在 Android 代码中实例化 React Native 模块,并调用其方法。

以下是一个简单的示例,演示如何在 Android 中调用 React Native 方法:

  1. 创建一个 Native Module

在 React Native 项目中,创建一个 Native Module,例如:

// MyModule.js

import { NativeModules } from 'react-native';

const MyModule = NativeModules.MyModule;

export default MyModule;

在该模块中,我们将使用 NativeModules API 导出一个名为 MyModule 的 Native Module。

  1. 添加 React Native 依赖项

在 Android 项目中,添加 React Native 依赖项。在 build.gradle 文件中添加以下行:

dependencies {
    implementation 'com.facebook.react:react-native:0.63.4'
}

这将添加 React Native 库到 Android 项目中。

  1. 实例化 React Native 模块并调用其方法

在 Android 代码中,实例化 MyModule 并调用其方法,例如:

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;

import com.example.MyModule;

public class MainActivity extends AppCompatActivity {
    private MyModule myModule;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      // 实例化 MyModule
      myModule = MyModule.getInstance();

      // 调用 MyModule 中的方法
      myModule.myMethod("Hello, React Native!", new Callback() {
        @Override
        public void invoke(Object... args) {
            // 处理回调
        }
      });
    }
}

在此示例中,我们实例化了 MyModule 并调用了其 myMethod 方法。该方法接受一个字符串参数和一个回调函数。在回调函数中,我们可以处理从 React Native 返回的数据。

这就是在 Android 中调用 React Native 方法的基本步骤。请注意,此示例仅用于演示目的,实际实现可能会有所不同。

JavaScript 引擎

React Native 使用的是 JavaScript 引擎是由 Facebook 开发的 JavaScriptCore 引擎,它是一个开源的 JavaScript 引擎,最初是为 Safari 浏览器开发的。JavaScriptCore 引擎是一个高性能的引擎,它支持 ECMAScript 5 和 ECMAScript 6 标准,并且可以在 iOS 和 Android 平台上运行。React Native 还支持使用 V8 引擎,但需要手动配置。

React Native 中的 JavaScriptCore 是一个内置的 JavaScript 引擎,它是由苹果公司开发的,用于在 iOS 和 macOS 上运行 JavaScript 代码。在 React Native 中,JavaScriptCore 负责解析和执行 JavaScript 代码,并将其转换为原生代码,以便在移动设备上运行。

JavaScriptCore 的工作原理如下:

  1. 解析 JavaScript 代码:JavaScriptCore 会将 JavaScript 代码解析成抽象语法树(AST)。
  2. 生成字节码:JavaScriptCore 会将 AST 转换为字节码,这是一种中间代码,可以更快地执行。
  3. JIT 编译:JavaScriptCore 还支持即时编译(JIT),它会将字节码转换为本地机器代码,以便更快地执行。
  4. 执行代码:JavaScriptCore 会执行生成的机器代码,并将结果返回给 React Native。
  5. 与原生代码交互:JavaScriptCore 还提供了一些 API,可以让 JavaScript 代码与原生代码进行交互,例如调用原生模块或组件。

渲染整体流程

如下图所示:

react.webp

渲染器

React Native 是一种用于构建移动应用程序的跨平台框架,它使用了类似于 React 的声明性编程模型来描述界面的渲染方式。React Native 中的渲染器负责将这些声明性的描述转化为真实的用户界面。

React Native 的渲染器工作原理可以分为以下几个步骤:

  • 生成虚拟 DOM:React Native 使用类似于 React 的虚拟 DOM 模型来描述用户界面。当开发者写下组件代码时,React Native 解析组件的结构和属性,并根据这些信息生成一个对应的虚拟 DOM 对象。
  • 对比前后虚拟 DOM:React Native 使用一个 Diff 算法来比较前后两个虚拟 DOM 对象的不同之处。这个算法会遍历前后两个虚拟 DOM 对象,找出它们之间的差异,然后只更新需要变更的部分。
  • 生成原生组件:React Native 的渲染器会根据虚拟 DOM 对象生成原生的 UI 组件,这些原生组件将会直接呈现在设备的屏幕上。
  • 处理交互事件:当用户与应用程序进行交互时,React Native 的渲染器会将事件转化为标准的 JavaScript 事件,并将其传递给相应的组件处理。这个过程涉及到从原生端向 JavaScript 端发送事件通知,以及从 JavaScript 端向原生端发送命令的通信。
  • 处理布局和样式:React Native 使用一种称为 Flexbox 的布局模型来实现跨平台的自适应布局。开发者可以使用类似于 CSS 的样式来定义组件的样式属性,并使用 Flexbox 来管理这些组件的位置和大小。

总的来说,React Native 的渲染器将虚拟 DOM 对象转化为原生的 UI 组件,并在需要更新或重新渲染时,使用 Diff 算法来找到需要变更的部分,并只更新这些部分。这种方式可以让应用程序在不同平台之间保持一致的外观和性能表现。

热加载

React Native 热加载原理是基于 JavaScript 的动态加载机制实现的。在 React Native 中,JavaScript 代码是通过 JavaScriptCore 引擎解释执行的,因此可以通过动态加载新的 JavaScript 代码来实现热更新。

具体实现方式如下:

  1. 在应用启动时,加载初始的 JavaScript 代码。
  2. 在应用运行过程中,检测到有新的 JavaScript 代码需要更新时,通过网络请求获取新的 JavaScript 代码。
  3. 将新的 JavaScript 代码保存到本地文件系统中。
  4. 使用 JavaScriptCore 引擎加载新的 JavaScript 代码,并替换原有的 JavaScript 代码。
  5. 重新渲染应用界面,使新的 JavaScript 代码生效。
需要注意的是,由于 React Native 中的组件和原生组件是通过桥接机制实现的,因此热更新只能更新 JavaScript 代码,无法更新原生组件。如果需要更新原生组件,需要重新打包应用并重新发布。

热更新

React Native 热更新的基本流程:

  1. 开发人员在服务器上发布新版本的代码。
  2. 应用程序检查服务器上是否有新版本可用。
  3. 如果有新版本可用,则应用程序下载新代码包。
  4. 应用程序使用新代码包更新本地代码。
  5. 应用程序重新启动以加载新代码。

在 React Native 中,可以使用第三方库(如 CodePush)来实现热更新。这些库提供了简化热更新流程的 API 和工具。

5

评论 (0)

取消