You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@protocol RCTCxxBridgeDelegate <RCTBridgeDelegate>
/** * In the RCTCxxBridge, if this method is implemented, return a * ExecutorFactory instance which can be used to create the executor. * If not implemented, or returns an empty pointer, JSIExecutorFactory * will be used with a JSCRuntime.*/
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge;
@end
因此可以知道,Reanimated 团队通过实现该协议,实现了自己的 JSI 运行时实例,即是官方提到的 Separate JavaScript VM。找到 RN 官方调用位置:
// RCTCxxBridge.mm
- (void)start
{
...
// Prepare executor factory (shared_ptr for copy into block)
std::shared_ptr<JSExecutorFactory> executorFactory;
if (!self.executorClass) {
if ([self.delegate conformsToProtocol:@protocol(RCTCxxBridgeDelegate)]) {
id<RCTCxxBridgeDelegate> cxxDelegate = (id<RCTCxxBridgeDelegate>) self.delegate;
executorFactory = [cxxDelegate jsExecutorFactoryForBridge:self];
}
...
}
}
背景
最近准备在 App 中接入 Reanimated 和 GestureHandler,之前其实尝试接过,不过有未知报错,后续因为有业务跟进,便一再搁置。前段时间领导提到动效库的必要性,考虑到这两个库的高性能特性,因此再次尝试接入。
接入
babel-preset缺失
首次接入时,两者版本分别是
Reanimated@2.8.0
、GestureHandler@2.4.0
,基本属于最新稳定版本。参照官方文档的 安装步骤,在项目根目录添加了babel.config.js
配置文件,并补充相应配置:通过打进 XRN 的方式在工程中引用,并新建相应的测试页面,发现启动时报错:
想到可能是因为新增 babel 的配置文件导致语法解析问题,因此上 RN 官网找到 0.62.x 版本对应的配置内容,补充后的内容:
ReanimatedModule缺失
清除缓存重新运行
yarn start --reset-cache
,发现依然报错:单纯报错信息上看,
InnerNativeModule
为 undefined 了,从红屏的源码调用栈来看,最终找到 NativeReanimated.ts :假设
global.__reanimatedModuleProxy
为空,那么通过ReanimatedModule?.installTurboModule()
的方式手动赋值,继续搜索installTurboModule
方法:是个空实现!继续找到 UIResponder+Reanimated.mm:
到这里发现有一个宏标记
DONT_AUTOINSTALL_REANIMATED
,从命名上基本就能知道他是干嘛的了,所以100%可以确定 Reanimate 具备自动初始化的能力,那么初始化方法jsExecutorFactoryForBridge
到底是怎么调用的?实际上
jsExecutorFactoryForBridge
来自 RN 官方的 RCTCxxBridgeDelegate 协议,查看官方解释:因此可以知道,Reanimated 团队通过实现该协议,实现了自己的 JSI 运行时实例,即是官方提到的
Separate JavaScript VM
。找到 RN 官方调用位置:所以 Reanimated 团队用了比较 hack 的方式,在 RN 初始化 Bridge 实例的过程中,来达到自动初始化 ReanimatedModule 的目的。
XRNManager背锅
通过以上源码,基本梳理清楚了 Reanimated 的整个初始化过程。但是不禁有疑问,为何会导致自动初始化失败?到底是什么环节导致问题?实际问题就出现在
UIResponder+Reanimated
和RCTCxxBridge#delegate
上:UIResponder+Reanimated
分类实现了对应的协议方法,实际上已经在运行时中为 UIResponder 的 Metaclass 添加了jsExecutorFactoryForBridge
方法[cxxDelegate jsExecutorFactoryForBridge:self]
实际就是[aAppDelegate jsExecutorFactoryForBridge:self]
目前 XRN 提供了适配层,整个 RN 运行环境的初始化工作都由 XRNManager 完成,而 XRNManager 是 NSObject 的子类,并非继承自 UIResponder,因此
[self.delegate conformsToProtocol:@protocol(RCTCxxBridgeDelegate)]
返回结果其实是 NO,也就无法完成后续的初始化逻辑了。解决方案
修改 XRNManager 继承自 UIResponder 即可。重新打包 XRN 后,验证通过。
参考资料
The text was updated successfully, but these errors were encountered: