APP中RN页面热更新流程-ReactNative源码分析

这篇具有很好参考价值的文章主要介绍了APP中RN页面热更新流程-ReactNative源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

平时使用WebStorm或VSCode对RN工程中的文件修改后,在键盘上按一下快捷cmd+s进行文件保存,此时当前调试的RN页面就会自动进行刷新,这是RN开发相比于原生开发一个很大的优点:热更新。
那么,从按一下快捷cmd+s到RN页面展示出最新的JS页面,这个过程是怎样发生的呢?下面根据时间顺序来梳理一下。
这里约定后面说的原生部分是指iOS端,ReactNative源码分析指的是iOS端集成的RN框架分析。
 
原生APP中RN页面的热更新简要流程
React Native应用包含两部分:原生代码和JavaScript代码。JavaScript和原生代码通信的桥梁是Bridge,而Bridge的实现又依赖于JSThread的runloop。
当JS有消息要传递给原生时,它会把消息封装成事件放入到JSThread的runloop的事件队列中,而JSThread的runloop会监听消息队列中的事件,一旦有事件需要处理,就会将其交给Bridge处理,从而实现JavaScript和原生代码的相互调用和数据传输。
 
基于JavaScript和原生代码的消息传递机制,RN热更新步骤如下:
1.在iOS原生中的RN页面触发热更新时,首先是JS环境中的websocket收到了Metro服务器的通知,在这个通知中包含了需要更新的JS bundle的URL地址,然后js将这个通知事件放到了JSThread的runloop中传到了RCTCxxBridge。
2.RCTCxxBridge收到热更新事件后,调用JavaScriptCore框架中的方法来执行一个JavaScript脚本,这个脚本会告诉JavaScript环境去下载新的JS bundle并执行它。事件又回到了JS。
3.JavaScript环境调用下载命令向远程服务器请求新的JS bundle,事件又被转回到了原生侧。
4.原生侧下载最新的bundle.js,下载完成后调用加载,执行js方法。
5.重新设置RN页面的根组件。
 
热更新触发条件
React Native在调试模式下有两种热更新方式:Hot Reloading和Live Reload。Hot Reloading可以实现代码的增量更新,而Live Reload技术则是全量更新。
下面以在index.js中新增一个组件注册语句为例。
在RN项目中index.js是ReactNative项目的入口文件,RN启动时首先会执行这个文件,把组件注册到AppRegistry中,这里在index.js的文件底部顺序添加一个组件注册,然后按快捷键cmd+s保存修改
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的代码如下:
APP中RN页面热更新流程-ReactNative源码分析
在iOS端ReactNative框架中,RCTCxxBridge文件中的+ (void)runRunLoop方法内负责创建并运行JS引擎对应的jsThread的runloop。它在APP启动时被创建,用来处理js引擎的任务和事件,并保证了_jsThread的常驻,不被销毁。
runloop被注册时机在RN框架启动时:
APP中RN页面热更新流程-ReactNative源码分析
js引擎收到服务器的通知后,被包成一个原生runloop的事件源放入到事件队列中,然后jsThread的runloop开始处理事件。
APP中RN页面热更新流程-ReactNative源码分析
然后把事件加入到RCTMessageThread中进行异步处理
APP中RN页面热更新流程-ReactNative源码分析
RCTCxxBridge调用js脚本,让js处理与最新bundle.js下载相关的事件。把事件传入到js事件队列中
APP中RN页面热更新流程-ReactNative源码分析
js引擎处理完JS层面的事件后,将事件转回给原生,让原生代码执行实际的下载工作
APP中RN页面热更新流程-ReactNative源码分析
原生侧的RCTDevSettings模块的reloadWithReason:方法进行处理。调用ReloadCommand监听的触发器,进行触发reloadCommand命令
APP中RN页面热更新流程-ReactNative源码分析
RCTReloadCommand发送didReceiveReloadCommand收到下载指令
APP中RN页面热更新流程-ReactNative源码分析
接着调用RCTBridge中的didReceiveReloadCommand方法,RCTBridge中销毁之前的js缓存,调用setUp进行js环境重置,js资源下载
APP中RN页面热更新流程-ReactNative源码分析
js资源下载完成后,执行js代码
APP中RN页面热更新流程-ReactNative源码分析
js资源reload完成后,调用js引擎,展示目标组件
APP中RN页面热更新流程-ReactNative源码分析
当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页面的热更新主要流程结束。文章来源地址https://www.toymoban.com/news/detail-449628.html

 

到了这里,关于APP中RN页面热更新流程-ReactNative源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uni-app: onBackPress() 监听页面返回 - 更新数据

    生命周期 - onBackPress() 监听页面返回 函数名 说明 平台差异说明 onBackPress 监听页面返回 ,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解。支付宝小程序只有真机

    2024年02月11日
    浏览(64)
  • android源码学习- APP启动流程(android12源码)

    百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分)。所以我结合网上现有的文章,以及源码的阅读和调试,耗费了3整天的时间,力求写出一篇最完整,最详细,最通俗易懂的文章,

    2024年02月11日
    浏览(46)
  • 直播带货app开发开发流程分析

    随着小视频管理体系愈来愈变成人们的生活中的一部分,也随之短视频卖货逐步形成岗位内主流的转现方式,将短视频平台生产制造变成短视频带货体系计划愈来愈多,那样,把小视频管理体系开发设计变成短视频带货体系必须两步? 需求分析:明确项目的目标、功能和特性

    2024年02月16日
    浏览(44)
  • 帝国cms后台生成更新后,前台页面显示空白的原因分析

    帝国cms后台生成更新内容页后,前台页面显示空白的原因有以下几种: 1.查看下这个栏目设置的问题 看看模板选项里面 选择内容页模板了吗 2.查看下目录是否有写入权限 3.查看下自己的网站空间是否满了 基本上就是这种问题了 不过如果是网站使用了cdn,刚好生成的瞬间内容

    2024年02月03日
    浏览(55)
  • UI绘制流程分析(前篇)--App与Activity的启动

    彻底搞懂UI绘制流程,看该系列就够了 作为安卓开发最重要的知识点之一,UI绘制无疑是必须掌握的,要想搞懂它的测量、布局和绘制,得先理解它的整个流程,但现在让我们把时间再往前拨一下,先要从App启动流程以及Activity启动流程讲起。 提示:以下是本篇文章正文内容

    2024年02月16日
    浏览(52)
  • Spring源码分析(五) 事务全流程分析

    @Transactional 注解的属性信息 name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器 propagation 事务的传播行为,默认值为 REQUIRED。 isolation 事务的隔离度,默认值采用 DEFAULT。 timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完

    2024年02月07日
    浏览(36)
  • ReactNative项目构建分析与思考之native_modules.gradle

    上一篇文章分析完 react-native-gradle-plugin 后,我们知道了react-native-gradle-plugin 主要是对依赖环境,以及RN的依赖版本进行管理。 本篇文章来接着分析 native_modules.gradle 这个脚本,这个脚本是React Native构建中比较重要的一个角色。 这是一个源码形式的脚本文件,虽然只有一个文件

    2024年03月20日
    浏览(41)
  • okhttp源码简单流程分析

    拦截器详细解析可以看大佬简书 \\\"https://www.jianshu.com/p/6fac73f7570f\\\"和 “https://www.jianshu.com/p/3c740829475c” okhttp请求流程 1:OkHttpClient okHttpClient = new OkHttpClient.Builder() 构建一个okhttpClient对象,传入你想传入的对象,不传就是默认的; 2:构建request对象 Request request = new Request.Builder(

    2024年02月12日
    浏览(32)
  • zookeeper选举流程源码分析

    zookeeper选举流程源码分析 选举的代码主要是在 QuorumPeer.java 这个类中。 它有一个内部枚举类,用来表示当前节点的状态。 LOOKING: 当前节点在选举过程中 FOLLOWING:当前节点是从节点 LEADING: 当前节点是主节点 OBSERVING: 当前节点是观察者状态,这种状态的节点不参与选举的投

    2024年02月11日
    浏览(42)
  • MediaCodec源码分析 configure流程

    本文梳理MediaCodec configure流程,基于7.0代码,这里只分析AVC和HEVC的视频硬解,流程图如下。 代码见: frameworks/base/media/java/android/media/MediaCodec.java frameworks/base/media/jni/android_media_MediaCodec.h frameworks/base/media/jni/android_media_MediaCodec.cpp frameworks/av/media/libstagefright/MediaCodec.cpp frameworks/

    2024年02月09日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包