原生模块生命周期
在 React Native 中,原生模块是单例的。原生模块基础设施会在首次访问时惰性创建原生模块,并在应用需要时一直保留它。这是一种性能优化,可以避免在应用启动时急切创建原生模块的开销,从而确保更快的启动时间。
在纯 React Native 应用中,原生模块只创建一次,并且永远不会被销毁。然而,在更复杂的应用中,可能存在原生模块被销毁和重新创建的用例。例如,想象一个混合了原生视图和 React Native 界面的棕地应用,如与现有应用集成指南中所示。在这种情况下,当用户从 React Native 界面导航离开时销毁 React Native 实例,并在用户导航回该界面时重新创建它,这可能是合理的。
当这种情况发生时,无状态的原生模块不会引起任何问题。然而,对于有状态的原生模块,可能需要适当地使原生模块失效,以确保状态被重置和资源被释放。
在本指南中,你将探讨如何正确地初始化和使原生模块失效。本指南假设你熟悉如何编写原生模块,并且能够自如地编写原生代码。如果你不熟悉原生模块,请先阅读原生模块指南。
Android
对于 Android,所有原生模块都已实现一个定义了两个方法(initialize()
和 invalidate()
)的 TurboModule 接口。
当原生模块被创建时,原生模块基础设施会调用 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。