在2018 post中,Facebook工程师声称:
React Native旨在返回列出要执行的突变的单个JSON消息,例如
[["createView", attrs], ["manageChildren", ...]]
。我们将整个系统设计为永远不依赖于获取同步响应,并确保该列表中的所有内容都可以完全序列化为JSON并返回。
React Native codebase * 中的哪个是确切的代码,负责此功能(构建JSON)?或者引用的声明可能是谎言"简化"?
我拼命想找到它,但似乎是在圈子里奔跑;每当我发现一条最初似乎看起来很有前途的轨道时,它似乎永远无法将我带到一个可以生成这样的JSON的地方:(
* 请注意,我对 Android 代码库特别感兴趣;理想情况下, RN v0.55 ,这是写作时的最新版本。
如果可能,我也对补充"反向"码。我的意思是,我认为" native" (在Android的情况下为Java)代码也必须发送一些"事件"在某些时候向JS发回信号,我认为他们也是JSON。那么,这个代码在哪里生活? (我对接收和反序列化JSON的JS代码感兴趣。)
(另外,我非常感谢您了解这些"低级"功能(发送和接收JSON)是否可以从JS中以原始形式访问{{3基于应用程序;但这在答案中是100%可选的,因为我有理由相信,一旦我知道上面主要问题的答案,我就能自己找到答案。 )
注意:对于完整的披露,我也交叉发布了这个问题Expo,但截至撰写时尚无答案。当HN上的讨论主题变得过时时,我打算从此处删除此注释。
基于on HN,我开始模糊地认为概念/关键字名为" BatchedBridge
"可能与我正在寻找的东西非常接近。我的直觉似乎告诉我,这可能是朝着正确方向迈出的第一步。我发现了一篇描述a "Related" question suggested by SO的博客文章,据报道其结果如下所示:
{type: 1, module: "WebSocketModule", method: "addListener", args: Array(1)}
{type: 1, module: "WebSocketModule", method: "connect", args: Array(4)}
{type: 0, module: "RCTDeviceEventEmitter", method: "emit", args: Array(2)}
{type: 1, module: "Timing", method: "createTimer", args: Array(4)}
同一博客上的另一篇文章展示了如何how to observe messages flying both ways through BatchedBridge。这可以回答我的问题的最后一个可选部分的一半,关于如何在Expo中订阅来自JS的Java事件。 (在Java中:this.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("onSessionConnect", params);
,在JS中:DeviceEventEmitter.addListener('onSessionConnect', (event) => { console.log(event); });
)
另一个有趣的send events from Java to JS over this "bridge", and listen to them in JS,是通过使用Google搜索本地BatchedBridge'作为关键词。
构建JSON的地方可能为article on RN internals,但我不太确定:
550 void JSCExecutor::callNativeModules(Value&& value) {
...
556 auto calls = value.toJSONString();
557 m_delegate->callNativeModules(*this, folly::parseJson(calls), true);
称为例如line 556 below:
624 void JSCExecutor::invokeCallback(
625 const double callbackId,
626 const folly::dynamic& arguments) {
...
628 auto result = [&] {
...
634 return m_invokeCallbackAndReturnFlushedQueueJS->callAsFunction(
635 {Value::makeNumber(m_context, callbackId),
636 Value::fromDynamic(m_context, std::move(arguments))});
...
642 callNativeModules(std::move(result));
答案 0 :(得分:2)
根据问题中链接的文章以及2015年的some videos,经过一天的挖掘,我相信它确实是BatchedBridge
,又名{{ 1}},这是在Java / Swift和JS之间调用的总线。
如果我理解正确, JS-> Java调用与MessageQueue.enqueueNativeCall完成,定义为:
MessageQueue
虽然 Java-> JS调用是通过以下任何一个函数完成的(在同一个文件中):
enqueueNativeCall(
moduleID: number,
methodID: number,
params: any[],
onFail: ?Function,
onSucc: ?Function,
)
这实际上仍然没有回答关于“JSON在哪里?”的问题,但实际上我更感兴趣的是找到总线并验证是否它正在流经它的JSON。虽然我现在甚至不确定它是否最终成为实际的JSON字符串,但我相信它至少是“意识形态上的”JSON。在callFunctionReturnFlushedQueue(module: string, method: string, args: any[])
callFunctionReturnResultAndFlushedQueue(module: string, method: string, args: any[])
invokeCallbackAndReturnFlushedQueue(cbID: number, args: any[])
IIUC上似乎不允许使用非JSON兼容的对象,我相信“函数指针/回调”会转换为函数名称,因此可以从Java异步调用它们。我相信函数结果被忽略(即假设所有JS函数都有MessageQueue
返回类型)。
编辑: void
似乎返回了JS函数的结果,因此它似乎必须是非异步(阻塞)。但在搜索callFunctionReturnResultAndFlushedQueue
和m_callFunctionReturnResultAndFlushedQueueJS
的反应原生仓库后,似乎没有任何一个在任何地方被调用。在C ++中你永远不可能100%肯定,但是现在我会交叉指责并认为可以安全地忽略它。