RN初始化函数调用过程
2016-08-05 16:38:02 0 举报
在RN(React Native)中,初始化函数是在应用程序启动时自动调用的。这个函数通常命名为`App`,并在所有组件被渲染之前执行。在这个函数中,你可以进行一些初始化操作,例如设置状态、请求数据等。当用户打开应用程序时,`App`函数会被调用,然后它会返回一个根组件,该组件将被渲染到屏幕上。这个过程确保了应用程序在启动时就具备所需的功能和数据,从而提高了用户体验。总之,RN初始化函数是一个关键的生命周期方法,它在应用程序启动时执行,并为后续的操作奠定了基础。
作者其他创作
大纲/内容
processModuleConfig
- RemoteModules属性,用于保存Native端模块配置- Callbacks属性缓存js的回调方法- Queue事件队列用于处理各类事件等在构造函数中,解析Native传入的remoteModules JSON,转换成JS对象
核心说明
inJect config to JS
这段代码定义了一个全局模块NativeModules,遍历之前取到的remoteModules,将每一个module在NativeModules对象上扩展了一个getter方法,该方法中通过nativeRequireModuleConfig进一步加载模块的详细信息,通过processModuleConfig对模块信息进行预处理。进一步分析代码就可以发现这个方法其实是Native中定义的全局JS Block(nativeRequireModuleConfig)。
setUp
MessageQueue.js
get Models Configs
根据上一步MessageQueue的逻辑,继续往下跟踪_genModules函数,可以看到在MessageQueue已经对Native注入的Module Config做了一次预处理,如果debug模式可以看到大致的数据结构会转换成如下表中所示结构(其中HTSimepleAPI是一个自定义模块)。
创建bridge,这是核心
源码执行过程
config = [\"HTSimpleAPI\
ExcuseSource Code
Lazily Config Methods
初始化JS引擎。React Native在0.18中已经很好的抽象了原来了JSExecutor,目前实现了RCTWebSocketExecutor和RCTJSCExecutor两个脚本引擎的封装,前者用于通过WebSocket链接到Chrome调试,后者则是内置默认引擎直接通过IOS SDK JSContext来实现相关的逻辑。另外,在本阶段还会通过block hook的方式注册部分核心API- nativeRequireModuleConfig:用于在JS端获取对应的Native Module,在0.14后的版本React Native已经对初始化模块做了部分优化,把关于Native Module Method部分的加载工作放置在requireModuleConfig时才做- nativeLoggingHook:调用Native写入日志- nativeFlushQueueImmediate:手动触发执行当前Native Call队列中所有的Native处理请求- nativePerformanceNow:用于性能统计,获取当前Native的绝对时间(毫秒)对于模块类中想要声明的方法,需要添加RCT_EXPORT_METHOD宏。它会给方法名添加” rct_export “前缀。
createBatchedBridge
initWithParentBridge
initWithBundleURL:moduleName:initialProperties:launchOptions
- 在JS端也存在一个bridge模块BatchedBridge,也是与Native建立双向通信的关键所在- BatchedBridge是一个MessageQueue实例,它在创建时传入了__fbBatchedBridgeConfig值保存Native端支持的模块列表配置BatchedBridge在创建时将自己写入全局变量__fbBatchedBridge上,这样Native可以通过JSContext[@”__fbBatchedBridge”]访问到JS bridge对象
对于NativeModule,它们在上一步之后只有一个包含Module Name等简单信息的Module List的对象,只有在实际调用了该模块之后才会加载该模块的具体信息(比如暴露的API等)。
BatchedBridge.js
_genModules
start
真正的核心来了
文件
Load JS Source Code
第3、4步被加入到一个setupJSExecutorAndModuleConfig的dispatchGroup中,当这两步都完成后,触发该步。此时将第4步中生成的config注入到JS中,保存到名为__fbBatchedBridgeConfig 的js全局变量中。真正补全模块信息是当JS页面源码中,调用nativeRequireModuleConfig这个API使用指定模块(当然这也是非常符合Require按需加载的理念)时补全模块信息。
init Models
- 在JS端也存在一个bridge模块BatchedBridge,也是与Native建立双向通信的关键所在- BatchedBridge是一个MessageQueue实例,它在创建时传入了__fbBatchedBridgeConfig值保存Native端支持的模块列表配置BatchedBridge在创建时将自己写入全局变量__fbBatchedBridge上,这样Native可以通过JSContext[@”__fbBatchedBridge”]访问到JS bridge对象。
说明
这步将第2步中的Native模块类转换成Json,保存为remoteModuleConfig。注意在这里获取到的列表并非含有完整模块信息,而仅仅是一个Module List而已。
还记得第二部分第5步中Native端生成的模块配置表吗?结合它的结构,我们可以得知:对于Module&Method,在Native和JS端都以数组的形式存放,数组下标即为它们的ModuleID和MethodID。
JS的主入口index.ios.js在我们看来只有短短数十行,然而这不是最终执行的代码。React-Native页面源码需要通过Transform Server转换处理,并把转化后的模块一起合并为一个bundle.js,这个过程称为buildBundle。转换后的index.ios.bundle才是最终可被Javascript引擎直接解释运行的代码。下面我们按照主程序的逻辑来分析源码几个核心模块实现原理。在React Server中需要查看Bundle的模块映射关系可以直接访问:http://localhost:8081/index.ios.bundle.map,查看相关依赖和Bundle的缓存则可以访问: http://localhost:8081/debug
初始化
源码
RCTBatchedBridge.m
方法或函数
setUpExecutor
initWithBundleURL:moduleProvider:launchOptions
初始化加载React Native模块。该阶段会将所有注册的Native模块类整理保存到一个以Module Id为下标的数组对象中(同时还会保存一个以Module Name为Key的Dictionary,用于做索引方便后续的模块查找)。整个模块的基础初始化和注册过程在系统Load Class阶段就会完成。React Native对模块注册的实现还是比较巧妙、方便,只需要对目标类添加相应的宏即可。- 注册模块。实现RCTBridgeModule协议,并且在响应的Implemention文件中添加RCT_EXPORT_MODULE宏,该宏会为所在类自动添加一个+load方法,调用RCTBridge的RCTRegisterModule实现在Load Class阶段就完成模块注册工作。- 注册函数。待注册函数所在的类必须是已注册模块,在需要注册的函数前添加RCT_EXPORT_MODULE宏即可。当然这里需要注意的问题时模块初始化是一个同步任务,它必须被同步加载,所以当模块较多时势必会带来高延迟的问题,也是在新的版本中SDK将Module Method改为Lazy Load的原因之一。
0 条评论
下一页