Android 原生模块
原生模块和原生组件是我们传统架构中使用的稳定技术。 当新架构稳定后,它们将被弃用。新架构使用TurboModule和Fabric 组件来实现类似的功能。
欢迎来到 Android 的原生模块。请先阅读 原生模块简介 以了解原生模块的基本概念。
创建一个 Calendar 原生模块
在以下指南中,你将创建一个名为 CalendarModule
的原生模块,它允许你从 JavaScript 访问 Android 的日历 API。最终,你将能够从 JavaScript 中调用 CalendarModule.createCalendarEvent('Dinner Party', 'My House');
,从而调用 Java/Kotlin 方法创建一个日历事件。
设置
要开始,请在 Android Studio 中打开 React Native 应用程序中的 Android 项目。你可以在 React Native 应用中找到 Android 项目的位置:
我们建议使用 Android Studio 来编写你的原生代码。Android Studio 是一个为 Android 开发而构建的 IDE,使用它将帮助你快速解决代码语法错误等小问题。
我们还建议启用 Gradle Daemon 以加快你迭代 Java/Kotlin 代码时的构建速度。
创建自定义原生模块文件
第一步是在 android/app/src/main/java/com/your-app-name/
文件夹中创建 Java/Kotlin 文件(CalendarModule.java
或 CalendarModule.kt
)。该 Java/Kotlin 文件将包含您的原生模块 Java/Kotlin 类。
然后添加如下代码:
- java
- kotlin
package com.your-apps-package-name; // replace your-apps-package-name with your app’s package name
import com.facebook.react.bridge.NativeModule;
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 java.util.Map;
import java.util.HashMap;
public class CalendarModule extends ReactContextBaseJavaModule {
CalendarModule(ReactApplicationContext context) {
super(context);
}
}
package com.your-apps-package-name; // replace your-apps-package-name with your app’s package name
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
class CalendarModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {...}
正如您所看到的,您的CalendarModule
类继承自ReactContextBaseJavaModule
类。对于安卓系统,Java/Kotlin 原生模块是用扩展了ReactContextBaseJavaModule
并实现了 JavaScript 所需功能的类来编写的。
值得注意的是,从技术上讲,Java/Kotlin 类只需要扩展BaseJavaModule
类或实现NativeModule
接口,才能被 React Native 视为原生模块。
然而,我们建议您使用上面所示的ReactContextBaseJavaModule
。ReactContextBaseJavaModule
提供了ReactApplicationContext
(RAC)的访问权限,这对于需要挂钩到活动生命周期方法的原生模块非常有用。使用ReactContextBaseJavaModule
也将使您更容易在将来实现原生模块的类型安全性。为了实现原生模块类型安全性(将在未来版本中推出),React Native 会查看每个原生模块的 JavaScript 规范,并生成一个抽象基类,该基类扩展自ReactContextBaseJavaModule
。
模块名称
所有 Android 平台上的 Java/Kotlin 原生模块都需要实现 getName()
方法。该方法返回一个字符串,代表了原生模块的名称。这样,原生模块就可以通过其名称在 JavaScript 中被访问。例如,在下面的代码片段中,getName()
返回 "CalendarModule"
。
- java
- kotlin
// add to CalendarModule.java
@Override
public String getName() {
return "CalendarModule";
}
// add to CalendarModule.kt
override fun getName() = "CalendarModule"
可以通过以下方式在 JS 中访问原生模块:
const {CalendarModule} = ReactNative.NativeModules;
向 JavaScript 导出原生方法
接下来,您需要在原生模块中添加一个方法,该方法可以创建日历事件,并可以在 JavaScript 中调用。所有打算从 JavaScript 调用的原生模块方法都必须使用@ReactMethod
进行注解。
为CalendarModule
设置一个方法createCalendarEvent()
,可以通过CalendarModule.createCalendarEvent()
在 JS 中调用。目前,该方法将采用名称和位置作为字符串参数。参数类型选项将在稍后介绍。
- java
- kotlin
@ReactMethod
public void createCalendarEvent(String name, String location) {
}
@ReactMethod fun createCalendarEvent(name: String, location: String) {}
在您从应用程序调用该方法时,请在该方法中添加一条调试日志以确认它已被调用。以下是如何从 Android 工具包中导入并使用[Log](https:// developer.android.com/reference/android/util/Log)类的示例:
- java
- kotlin
import android.util.Log;
@ReactMethod
public void createCalendarEvent(String name, String location) {
Log.d("CalendarModule", "Create event called with name: " + name
+ " and location: " + location);
}
import android.util.Log
@ReactMethod
fun createCalendarEvent(name: String, location: String) {
Log.d("CalendarModule", "Create event called with name: $name and location: $location")
}
一旦您完成了原生模块的实现并将其与 JavaScript 连接起来,您便可以遵循这些步骤查看应用程序的日志。
同步方法
您可以将 isBlockingSynchronousMethod = true
传 递给原生方法,将其标记为同步方法。
- java
- kotlin
@ReactMethod(isBlockingSynchronousMethod = true)
@ReactMethod(isBlockingSynchronousMethod = true)
就目前而言,我们并不建议这么做,因为以同步的方式调用方法可能会带来严重的性能损失,并且可能会给你的原生模块引入与线程相关的 bug。此外,请注意,如果你选择启用 isBlockingSynchronousMethod
, 你的应用程序将无法再使用 Google Chrome 调试器。这是因为同步方法需要 JS VM 与应用程序共享内存。对于 Google Chrome 调试器而言,React Native 运行在 Google Chrome 中的 JS VM 内部,并通过 WebSockets 与移动设备进行异步通信。