(资料图片)
AppRegistry.registerComponent("FlatListDemo", () => FlatListDemo);这时本地的Packager服务会监听本地文件系统的变化,当有文件修改并保存时,Packager会运行RN命令行工具,自动生成一个新的bundle文件
react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/main.jsbundle --assets-dest ios然后将生成的bundle文件上传至服务器,接着Metro 服务器通过 WebSocket 链接发送消息给APP应用程序。
触发热更新
在APP中RN框架启动时,会在APP的JS运行上下文中创建一个websocket链接并与js服务器建立连接,它用于监听Metro服务器发来的bundle.js更新通知。当Packger打了新的bundle.js并上传到js服务器后,Metor服务器就会向与它链接的websocket发送更新通知,js引擎收到服务器的通知后,就会做后续的事件处理。具体js建立websocket的代码如下:在iOS端ReactNative框架中,RCTCxxBridge文件中的+ (void)runRunLoop方法内负责创建并运行JS引擎对应的jsThread的runloop。它在APP启动时被创建,用来处理js引擎的任务和事件,并保证了_jsThread的常驻,不被销毁。runloop被注册时机在RN框架启动时:js引擎收到服务器的通知后,被包成一个原生runloop的事件源放入到事件队列中,然后jsThread的runloop开始处理事件。然后把事件加入到RCTMessageThread中进行异步处理RCTCxxBridge调用js脚本,让js处理与最新bundle.js下载相关的事件。把事件传入到js事件队列中js引擎处理完JS层面的事件后,将事件转回给原生,让原生代码执行实际的下载工作原生侧的RCTDevSettings模块的reloadWithReason:方法进行处理。调用ReloadCommand监听的触发器,进行触发reloadCommand命令RCTReloadCommand发送didReceiveReloadCommand收到下载指令接着调用RCTBridge中的didReceiveReloadCommand方法,RCTBridge中销毁之前的js缓存,调用setUp进行js环境重置,js资源下载js资源下载完成后,执行js代码js资源reload完成后,调用js引擎,展示目标组件当js文件加载成功后,APP会重新创建一个RCTRootContentView, 并将旧的移除,把新的添加上去。新的RCTRootContentView.reactTag使用规则递增- (void)bundleFinishedLoading:(RCTBridge *)bridge{ RCTAssert(bridge != nil, @"Bridge cannot be nil"); if (!bridge.valid) { return; } [_contentView removeFromSuperview]; _contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds bridge:bridge reactTag:self.reactTag sizeFlexiblity:_sizeFlexibility]; [self runApplication:bridge]; _contentView.passThroughTouches = _passThroughTouches; [self insertSubview:_contentView atIndex:0]; if (_sizeFlexibility == RCTRootViewSizeFlexibilityNone) { self.intrinsicContentSize = self.bounds.size; }} - (void)runApplication:(RCTBridge *)bridge{ NSString *moduleName = _moduleName ?: @""; NSDictionary *appParameters = @{ @"rootTag" : _contentView.reactTag, @"initialProps" : _appProperties ?: @{}, }; RCTLogInfo(@"Running application %@ (%@)", moduleName, appParameters); [bridge enqueueJSCall:@"AppRegistry" method:@"runApplication" args:@[ moduleName, appParameters ] completion:NULL];}
至此,APP中RN页面的热更新主要流程结束。
关键词:
Copyright 2015-2022 起点礼仪网 版权所有 备案号:皖ICP备2022009963号-12 联系邮箱: 39 60 29 14 2@qq.com