React Native 学习记录 - JS和OC通信流程
什么是React Native
React Native 是Facebook出的一套开源框架,框架的作用是开发者特别是前端开发者可以使用JavaScript + React编写,但是会被“翻译”成原生代码执行。体验比纯粹的使用WebView去运行H5+JS语言更好,效率更高。
这是官方的介绍,可以让你构建出世界级的应用哦,是不是很心动?!
React Native enables you to build world-class application experiences on native platforms using a consistent developer experience based on JavaScript and React. The focus of React Native is on developer efficiency across all the platforms you care about - learn once, write anywhere. Facebook uses React Native in multiple production apps and will continue investing in React Native.
React Native给我们带来了什么
- 热更新
- 开发效率的提高
- 组件的复用
- 跨平台!?(官方提供的ui组件中也分*Android, *IOS,查阅了一下,有人说可以做到80%到90%共用,这个应该看具体应用场景了)
React Native现状
React Native原理
JavaScript 和 Objective-C 通信原理
参考这两篇文章学习React native Bridge 和 JS和OC通信原理
Native Module 核心代码
1 | //导出module符号给js使用 |
我们在查看`RCT_EXTERN`宏时可以学到一个小技巧:如果我们开发组件提供给其他模块使用,当我们不想暴露方法的实现时,可以使用这种方式,在方法名前面extern __attribute__((visibility("default")))
,告诉编译器这个符号不要在编译时解决,而是在链接时去解决。
1 | //导出方法符号给js使用 |
Runtime
程序加载时做的事情
Register All Export Modules 就是上面我们Native Code里面做的事情
获取js,可能本地,可能远程;同时通过所有ExportModuleClasses去初始化RCTModuleData:
- RCTBridget存储ModuleData的引用
- 判断ModuleClass的方法执行是否需要在主线程,如果不需要则新建一个串行队列 提供给该moduleCLass的方法执行
- 判断ModuleClass是否有需要导出的常量
初始化JavaScript Executor,这里如果我们不在Chrome里面调试,就是RCTJSCExecutor,否则就是RCTWebSocketExecutor。
- 初始化JavaScriptCore;
- 添加一些方法供Js调用,比如Js在调用我们的Native Code的方法时: 同时: ModuleClass对应的Json格式的config数据:
1
2
3
4
5
6
7
8
9
10[self addSynchronousHookWithName:@"nativeFlushQueueImmediate" usingBlock:^(NSArray<NSArray *> *calls){
RCTJSCExecutor *strongSelf = weakSelf;
if (!strongSelf.valid || !calls) {
return;
}
RCT_PROFILE_BEGIN_EVENT(0, @"nativeFlushQueueImmediate", nil);
[strongSelf->_bridge handleBuffer:calls batchEnded:NO];
RCT_PROFILE_END_EVENT(0, @"js_call", nil);
}];
1
2
3
4
5
6
7
8
9
10[
"CalendarManager",
{
"firstDayOfTheWeek": "Monday"
},
[
"addEvent",
"findEvents"
]
]注入JavaScript:
1
2
3
4
5
6
7
8
9
10
11- (void)injectJSONConfiguration:(NSString *)configJSON
onComplete:(void (^)(NSError *))onComplete
{
if (!_valid) {
return;
}
[_javaScriptExecutor injectJSONText:configJSON
asGlobalObjectNamed:@"__fbBatchedBridgeConfig"
callback:onComplete];
}就是将4拿到的
jsonConfig
赋值给__fbBatchedBridgeConfig
,在5中执行JS会用到执行2中获取的Js
通信
参考前面提到的博文(JS和OC通信原理 ),这篇介绍得很详细了。
渲染机制
1 | JSX -> Virtual DOM -> RCTUIManager(shadow queue) -> Native View (main queue) |
首先babel
会翻译JSX
为标准的ES5
, React的组件模型实现了一套Virtual DOM
,会比对当前正在显示的Virtual DOM
和将要显示的Virtual DOM
,做一个diff,然后将diff后的数据组装成消息结构通过JSBridge
发送给Native
端,这时Native在shadow queue
(非主线程)将消息组装成一个block
并push到队列里去,然后在一个恰当的时机flush所有的UI block
,此时是在主线程中调用。
看看别人怎么说
学习曲线
JavaScript
JSX
React
CSS-Layout
Flux
Github上的中英文有关ReactNative的学习仓库:
中文整理资料
英文整理资料
前端开发者还得了解常用的iOS以及Android的View结构以及移动设备的体验习惯。
完