1. 原生模块概述:什么是原生模块、原生模块的应用场景、原生模块与Web模块的对比

好,咱们直接进入正题。这门课的第一讲,我想先聊聊「原生模块」到底是个什么东西。

你可能听过很多概念——Native Module、原生插件、桥接层……说白了,原生模块就是一段用平台原生语言(Android 上用 Java/Kotlin,iOS 上用 Objective-C/Swift)写的代码,但它能被 JavaScript 环境调用。嗯,你可以把它想象成一座桥——桥的一头是 JS,另一头是系统底层能力。

1.1 什么是原生模块

我个人的理解很简单:原生模块就是让 JS 能调用系统 API 的中间层。

举个例子。你在 React Native 里写 console.log('hello'),这没问题,因为 JS 引擎自带这个能力。但如果你想读取手机通讯录、调用摄像头、获取设备指纹——这些 JS 本身做不到。这时候就需要原生模块出马了。

核心定义:原生模块是一个封装了平台特定功能的代码单元,通过桥接机制暴露给 JavaScript 层调用。

我在项目中遇到过不少新手,以为原生模块就是「用 Java 写个类」这么简单。其实没那么轻松。你写出来的类要遵循框架的注册规则,要处理好线程模型,还要考虑内存泄漏——这些坑我后面会一个一个讲。

1.2 原生模块的应用场景

什么时候你该考虑写原生模块?我总结了几个典型场景:

  • 性能敏感的操作——比如图像处理、视频编解码、大量数据计算。JS 跑这些太慢了,原生代码直接操作内存,快一个数量级。
  • 访问系统硬件——蓝牙、NFC、指纹识别、传感器。这些 API 只有原生层才能调用。
  • 复用已有的原生库——公司之前用 Java 写了个支付 SDK,你不想用 JS 重写一遍?封装成原生模块就行。
  • 后台任务与前台通知——JS 在后台会被挂起,原生代码可以跑 Service、注册 BroadcastReceiver。

我曾经接手过一个项目,需要在 Android 上实时处理摄像头帧做人脸检测。一开始团队用 JS 写,每帧处理要 200ms,卡得没法用。后来我改成原生模块,用 C++ 的 OpenCV 做处理,每帧降到 15ms。嗯,这就是原生模块的价值。

1.3 原生模块与 Web 模块的对比

你可能会问:Web 模块也能做很多事情啊,为什么非要原生?

咱们直接看对比表:

对比维度 原生模块 Web 模块
运行环境 系统底层(Java/ObjC) 浏览器 JS 引擎
性能 极高,直接操作内存 受限于 JS 引擎和 DOM
系统 API 访问 完全访问 受浏览器沙箱限制
跨平台 需分别实现 Android/iOS 一套代码多平台
调试难度 较高,需原生工具链 较低,浏览器 DevTools
热更新 通常需要发版 可随时更新

说白了,原生模块用开发效率换性能。Web 模块写起来快,但天花板低;原生模块写起来麻烦,但能做 Web 做不了的事。

我的建议:能用 Web 模块解决的,就别上原生。只有 Web 实在搞不定的时候,再考虑写原生模块。别为了炫技而过度设计。

1.4 一个简单的原生模块长什么样

光说不练假把式。我拿 React Native 举个例子,一个最简单的原生模块大概长这样:

// Android 端 (Java)
public class ToastModule extends ReactContextBaseJavaModule {
    @Override
    public String getName() {
        return "ToastModule";
    }

    @ReactMethod
    public void show(String message, int duration) {
        Toast.makeText(getReactApplicationContext(), message, duration).show();
    }
}

然后在 JS 端调用:

import { NativeModules } from 'react-native';
NativeModules.ToastModule.show('Hello from native!', Toast.LENGTH_SHORT);

你看,核心就三步:写一个原生类、注册到框架、JS 端调用。但实际项目中,你会遇到线程同步、生命周期管理、参数类型转换……这些才是真正的难点。

注意:我曾经犯过一个低级错误——在原生模块的 show 方法里直接做了网络请求。结果因为 Android 不允许在主线程做网络操作,直接崩溃。记住:耗时操作一定要放到子线程。

1.5 本章小结

这一章我们聊了三个核心问题:

  • 原生模块是 JS 与系统底层之间的桥梁
  • 它适用于性能敏感、硬件访问、库复用等场景
  • 与 Web 模块相比,它性能更强但开发成本更高

下一章我会带你手写第一个原生模块,从环境搭建到跑通 Hello World。到时候你会看到,其实入门没那么难——难的是把坑都踩一遍之后还能保持冷静。嗯,我当年就踩了不少坑,后面慢慢讲给你听。