跳到主要内容

原生模块生命周期

在 React Native 中,原生模块是单例的。原生模块基础设施会在首次访问时懒加载创建原生模块,并在应用需要时保留它。这是一种性能优化,避免了在应用启动时就急切地创建原生模块,从而保证启动速度更快。

在纯 React Native 应用中,原生模块只创建一次,并且永远不会被销毁。然而,在更复杂的应用中,可能存在销毁并重新创建原生模块的用例。举例来说,设想一个混合型应用,将一些原生视图和 React Native 界面混合使用,如整合现有应用指南中所述。在这种情况下,当用户离开 React Native 界面时销毁 React Native 实例,用户返回该界面时重新创建它是合理的。

当发生这种情况时,无状态的原生模块不会引起问题。然而,对于有状态的原生模块,正确地使原生模块失效以确保重置状态和释放资源可能是必要的。

本指南将介绍如何正确初始化和失效一个原生模块。假设你已经熟悉如何编写原生模块,并且能够编写原生代码。如果你还不熟悉原生模块,请先阅读原生模块指南

Android

在 Android 上,所有原生模块都实现了TurboModule接口,该接口定义了两个方法:initialize()invalidate()

initialize() 方法由原生模块基础设施在创建原生模块时调用。这是放置需要访问 ReactApplicationContext 的初始化代码的最佳位置。例如,核心中的一些实现了 initialize() 方法的原生模块有:BlobModuleNetworkingModule

invalidate() 方法由原生模块基础设施在销毁原生模块时调用。这是放置清理代码的最佳位置,用来重置原生模块状态和释放不再需要的资源,如内存和文件。核心中实现了 invalidate() 方法的一些原生模块有:DeviceInfoModuleNetworkModule

iOS

在 iOS 上,原生模块遵循 RCTTurboModule 协议。然而,该协议并不暴露 Android 的 TurboModule 类所提供的 initializeinvalidate 方法。

相反,在 iOS 上,有两个附加协议:RCTInitializingRCTInvalidating。这两个协议分别用于定义 initializeinvalidate 方法。

如果你的模块需要执行初始化代码,可以遵循 RCTInitializing 协议并实现 initialize 方法。为此,你需要:

  1. 修改 NativeModule.h 文件,添加以下内容:
NativeModule.h
+ #import <React/RCTInitializing.h>

//...

- @interface NativeModule : NSObject <NativeModuleSpec>
+ @interface NativeModule : NSObject <NativeModuleSpec, RCTInitializing>
//...
@end
  1. NativeModule.mm 文件中实现 initialize 方法:
NativeModule.mm
// ...

@implementation NativeModule

+- (void)initialize {
+ // 在这里添加初始化代码
+}

@end

核心中的一些实现了 initialize 方法的原生模块有:RCTBlobManagerRCTTiming

如果你的模块需要执行清理代码,则可以遵循 RCTInvalidating 协议并实现 invalidate 方法。为此,你需要:

  1. 修改 NativeModule.h 文件,添加以下内容:
NativeModule.h
+ #import <React/RCTInvalidating.h>

//...

- @interface NativeModule : NSObject <NativeModuleSpec>
+ @interface NativeModule : NSObject <NativeModuleSpec, RCTInvalidating>

//...

@end
  1. NativeModule.mm 文件中实现 invalidate 方法:
NativeModule.mm

// ...

@implementation NativeModule

+- (void)invalidate {
+ // 在这里添加清理代码
+}

@end

核心中实现了 invalidate 方法的一些原生模块有:RCTAppearanceRCTDeviceInfo