在APP启动后,RN框架开始启动。等RN框架启动后,就开始进行RN页面渲染了。
RN页面原生侧页面渲染的主要逻辑实现是在RCTUIManager和RCTShadowView完成的。
通过看UIMananger的源码可以看到,UIMananger导出给JS端的API接口在对UI的操作上,基本都会同时对 View 和 ShadowView 进行操作。
以更新视图为例:

RCTUIManager的作用
RCTUIManager的主要作用是负责管理React Native应用程序的视图的创建、更新和销毁;将原生组件注册到JS端;处理原生和React Native之间的通信;
具体如下:
1.视图的创建、更新和销毁。RCTUIManager负责创建并管理应用程序中的所有视图,包括文本、图像、按钮等。当需要更新或销毁视图时,RCTUIManager会负责处理相应的操作。
2.组件的注册。RCTUIManager负责注册应用程序中的所有组件,并提供相应的方法以便在React Native应用程序中使用。
3.原生和React Native之间的通信。RCTUIManager通过桥接层(Bridge)与原生平台进行通信,使得React Native应用程序可以在原生平台上运行和呈现UI界面。当React Native应用程序需要与原生平台进行交互时,RCTUIManager会负责处理相应的操作。
 
RCTShadowView的作用 
RCTShadowView的主要作用是在APP中创建一棵YaGoNode节点树,用于记录视图的样式、布局、事件响应等信息,用于描述真实视图的属性和布局,从而提高渲染性能和效率。,它和UIView的关系类似于前端的虚拟DOM树和DOM树,两者是一一对应的关系。js对View的操作会先更新虚拟DOM,然后ReactNative在合适的时机批量更新到真实的View上。
RN页面的创建
在创建自定义RNView供js使用时,一般在创建一个RNView时,都要创建一个对应的RNViewManager用于管理Native与js的通讯。
UIMananger的创建在RN框架启动时,它在创建时会通过RCT_EXPORT_METHOD()宏将操作view的添加,修改,删除,调整层级等方法注入给js,供js操作原生view
RN框架启动完成后则会进行RN页面渲染。
 
首先,js引擎执行rn代码,将rn中的组件转换成原生view展示到页面上。
js通过执行create代码,创建原生View

原生侧createView方法的主要执行步骤为:

RCT_EXPORT_METHOD(createView
: (nonnull NSNumber *)reactTag viewName
: (NSString *)viewName rootTag
: (nonnull NSNumber *)rootTag props
: (NSDictionary *)props)
1.根据模块名viewName从RCTBridge保存的全局变量中找到对应的模块信息
2.根据模块信息创建shadowview虚拟dom,保存到shadowView全局容器中
3.根据模块信息在主线程创建原生view,保存到view全局容器中
 
然后,执行setChildren:设置子视图
执行setChildren:设置子视图, 会将view添加到容器view的reactSubviews中(shadowView和UIView都是放到对应容器的reactSubviews属性中)[container insertReactSubview:view atIndex:index++];

原生侧setChildren方法的主要执行步骤为:

RCT_EXPORT_METHOD(setChildren : (nonnull NSNumber *)containerTag reactTags : (NSArray<NSNumber *> *)reactTags)
1.设置shadowView子视图,shadowView是设置到yoga树的叶子节点中:YGNodeInsertChild(_yogaNode, subview.yogaNode, (uint32_t)atIndex);
2.把设置view子视图任务添加到任务队列,[_pendingUIBlocks addObject:block];队列中的任务并不会立刻执行,而是等到合适的时机再执行。而当这个任务执行后,子View也并没有到真实的subviews中,而是放置到了reactSubviews关联属性中 objc_setAssociatedObject(self, @selector(reactSubviews), subviews, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
 
_pendingUIBlocks队列执行时机
在js执行期间,js引擎通过Bridge桥接,把涉及到UI操作的事件按顺序封装成UIBlock放到Native原生侧的_pendingUIBlocks中,在等js代码执行完成后,原生模块会触发一个UIManager.batchDidComplete事件,表示js批量任务执行完成,开始刷新uiPending队列中的UI任务了。因此,在 JavaScript 执行完成前,RN 页面的 UI 并不会立即刷新。
方法调用顺序:batchDidComplete -> _layoutAndMount -> flushUIBlocksWithCompletion。
_pendingUIBlocks中的UIBlock执行后,最终会生成真实的原生view
- (void)didUpdateReactSubviews
{
for (UIView *subview in self.reactSubviews) {
[self addSubview:subview];
}
}
 
RN页面更新
当组件调用了setState属性更新时,通过updateView:刷新视图。
当出现插入、删除、排序组件时,通过manageChildren:更新视图。
updateView:刷新视图
当在RN中通过setState更改属性,js会对应生成一个新的虚拟DOM,通过diff算法,对应新旧DOM树生成修改点,然后通过updateView事件,将属性更新更新到原生侧的shadowView和View的_UIPendingQueue中。
 
当出现插入、删除、排序组件时,通过manageChildren:更新视图
containerTag:表示容器组件的标识符,即将在其中管理子组件。
moveFromIndices和moveToIndices:表示要移动的子组件的原始位置和目标位置的索引。
addChildReactTags和addAtIndices:表示要添加的子组件的标识符和它们在父容器中的位置索引。
removeAtIndices:表示要从父容器中删除的子组件的位置索引。
registry:表示React组件的注册表,其中包含所有已注册的组件及其实例。

 
 
 
 

APP中RN页面渲染流程-ReactNative源码分析的更多相关文章

  1. Springboot学习04-默认错误页面加载机制源码分析

    Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...

  2. SpringMVC执行流程及源码分析

    SpringMVC流程及源码分析 前言 ​ 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...

  3. java中的==、equals()、hashCode()源码分析(转载)

    在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...

  4. Vue3中的响应式对象Reactive源码分析

    Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...

  5. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  6. Struts2请求处理流程及源码分析

    1.1 Struts2请求处理 1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionConte ...

  7. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

  8. Android应用层View绘制流程与源码分析

    1  背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...

  9. django Rest Framework----APIView 执行流程 APIView 源码分析

    在django—CBV源码分析中,我们是分析的from django.views import View下的执行流程,这篇博客我们介绍django Rest Framework下的APIView的源码 ...

  10. DRF认证流程及源码分析

    认证 前言 用户验证用户是否合法登陆. 部分内容在DRF视图的使用及源码流程分析讲解,建议先看讲解视图的这篇文章. 使用流程 认证使用的方法流程如下: 自定义认证类,继承BaseAuthenticat ...

随机推荐

  1. 记一次winfrom 面板改变背景图片

    this.panel1.BackgroundImage = Image.FromFile(@"D:\TestDemo\WindowsFormsApp2\WindowsFormsApp2\黑箭 ...

  2. 【随笔】Axios delete传递数组问题

    pre { overflow-y: auto; max-height: 300px } img { max-width: 500px; max-height: 300px } Axios delete ...

  3. 剑指offer 第18天

    第 18 天 搜索与回溯算法(中等) 剑指 Offer 55 - I. 二叉树的深度 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长 ...

  4. DevOps, HybridOps and AIOps浅谈

    DevOps, HybridOps and AIOps浅谈 DevOps的概念出现比较久了,很多的IT项目也都在实际的运用中.AIOps概念作为DevOps的升级版,也得到了很广大的关注,也出现了很多 ...

  5. python自动化测试pyautogui,pywinauto和pywin32组合使用初级

    1 前言PC 端自动化测试使用到的 python 模块主要有 pywinauto.win32gui.pyautogui,主要功能如下: pywinauto:主要使用到 Application 类,用于 ...

  6. python入门教程之二十邮件操作

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. python的smtplib提供了一 ...

  7. [Java/Arthas]Arthas The telnet port 3658 is used by process 13988 instead of target process 11208, y[转载]

    1 问题描述 Arthas 跟踪 一个已经在tomcat部署的工程quality,第一次使用过的是135091号进程,后来出现问题,换进程连接,报错如上图所示,提示端口占用.原因是上次连接了一个进程, ...

  8. 深度学习之PyTorch实战(5)——对CrossEntropyLoss损失函数的理解与学习

    其实这个笔记起源于一个报错,报错内容也很简单,希望传入一个三维的tensor,但是得到了一个四维. RuntimeError: only batches of spatial targets supp ...

  9. day60:Linux压缩与打包&用户管理&用户提权sudo&grep,sed,awk,sort,uniq

    目录 1.文件管理-压缩与打包 2.用户管理 用户怎么查 如何创建用户 创建的用户信息都存储在哪? 用户存储密码的文件 如何为用户设定密码? 3.用户组 4.用户提权相关 5.Extra:额外补充 文 ...

  10. Semantic Kernel 入门系列:🥑Memory内存

    了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...