原生模块生命周期
在 React Native 中,原生模块是单例的。原生模块基础设施在第一次访问时延迟创建原生模块,并在应用程序需要时保留它。这是一种性能优化,可以避免在应用程序启动时急于创建原生模块的开销,并确保更快的启动时间。
在纯 React Native 应用程序中,原生模块只创建一次,永不销毁。然而,在更复杂的应用程序中,可能存在原生模块被销毁和重新创建的用例。例如,想象一个混合了原生视图和 React Native 界面的“棕地”应用程序,如与现有应用程序集成指南中所示。在这种情况下,当用户从 React Native 界面导航离开时销毁 React Native 实例,并在用户导航回该界面时重新创建它可能是有意义的。
发生这种情况时,无状态原生模块不会引起任何问题。但是,对于有状态原生模块,可能需要正确使原生模块失效,以确保状态被重置和资源被释放。
本指南将探讨如何正确初始化和使原生模块失效。本指南假设您熟悉如何编写原生模块并且熟悉编写原生代码。如果您不熟悉原生模块,请先阅读原生模块指南。
Android
在 Android 方面,所有原生模块都已实现一个 TurboModule 接口,该接口定义了两个方法:initialize()
和 invalidate()
。
initialize()
方法由原生模块基础设施在原生模块创建时调用。例如,这是放置所有需要访问 ReactApplicationContext 的初始化代码的最佳位置。以下是核心中实现 initialize()
方法的一些原生模块:BlobModule、NetworkingModule。
当原生模块被销毁时,原生模块基础设施会调用 invalidate()
方法。这是放置所有清理代码、重置原生模块状态和释放不再需要的资源(如内存和文件)的最佳位置。以下是核心中实现 invalidate()
方法的一些原生模块:DeviceInfoModule、NetworkModule
iOS
在 iOS 上,原生模块符合 RCTTurboModule
协议。然而,此协议不公开 Android 的 TurboModule
类所公开的 initialize
和 invalidate
方法。
相反,在 iOS 上,还有两个额外的协议:RCTInitializing
和 RCTInvalidating
。这些协议分别用于定义 initialize
和 invalidate
方法。
如果您的模块需要运行一些初始化代码,则可以遵循 RCTInitializing
协议并实现 initialize
方法。为此,您必须:
- 通过添加以下行修改
NativeModule.h
文件
+ #import <React/RCTInitializing.h>
//...
- @interface NativeModule : NSObject <NativeModuleSpec>
+ @interface NativeModule : NSObject <NativeModuleSpec, RCTInitializing>
//...
@end
- 在
NativeModule.mm
文件中实现initialize
方法
// ...
@implementation NativeModule
+- (void)initialize {
+ // add the initialization code here
+}
@end
以下是核心中实现 initialize
方法的一些原生模块:RCTBlobManager、RCTTiming。
如果您的模块需要运行一些清理代码,则可以遵循 RCTInvalidating
协议并实现 invalidate
方法。为此,您必须:
- 通过添加以下行修改
NativeModule.h
文件
+ #import <React/RCTInvalidating.h>
//...
- @interface NativeModule : NSObject <NativeModuleSpec>
+ @interface NativeModule : NSObject <NativeModuleSpec, RCTInvalidating>
//...
@end
- 在
NativeModule.mm
文件中实现invalidate
方法
// ...
@implementation NativeModule
+- (void)invalidate {
+ // add the cleanup code here
+}
@end
以下是核心中实现 invalidate
方法的一些原生模块:RCTAppearance、RCTDeviceInfo。