// If we have a delegate, we need to call it; we pass a null list to
// callNativeModules, since we know there are no native calls, without
// calling into JS again. If no calls were made and there’s no delegate,
// nothing happens, which is correct.
callNativeModules(Value::makeNull(m_context));
}
}
上面提到flush()方法调用MessageQueue.js的flushedQueue()方法,这是如何做到的呢?🤔。
事实上这是由bindBridge()方法来完成的,bindBridge()从__fbBatchedBridge(__fbBatchedBridge也是被MessageQueue.js设置为全局变量,供C++层读取)对象中取出MessageQueue.js里的四个方法:
- callFunctionReturnFlushedQueue()
- invokeCallbackAndReturnFlushedQueue()
- flushedQueue()
- callFunctionReturnResultAndFlushedQueue()
并分别存在三个C++变量中:
- m_callFunctionReturnFlushedQueueJS
- m_invokeCallbackAndReturnFlushedQueueJS
- m_flushedQueueJS
- m_callFunctionReturnResultAndFlushedQueueJS
这样C++就可以调用这四个JS方法。
void JSCExecutor::bindBridge() throw(JSException) {
SystraceSection s(“JSCExecutor::bindBridge”);
std::call_once(m_bindFlag, [this] {
auto global = Object::getGlobalObject(m_context);
auto batchedBridgeValue = global.getProperty(“__fbBatchedBridge”);
if (batchedBridgeValue.isUndefined()) {
auto requireBatchedBridge = global.getProperty(“__fbRequireBatchedBridge”);
if (!requireBatchedBridge.isUndefined()) {
batchedBridgeValue = requireBatchedBridge.asObject().callAsFunction({});
}
if (batchedBridgeValue.isUndefined()) {
throw JSException(“Could not get BatchedBridge, make sure your bundle is packaged correctly”);
}
}
auto batchedBridge = batchedBridgeValue.asObject();
m_callFunctionReturnFlushedQueueJS = batchedBridge.getProperty(“callFunctionReturnFlushedQueue”).asObject();
m_invokeCallbackAndReturnFlushedQueueJS = batchedBridge.getProperty(“invokeCallbackAndReturnFlushedQueue”).asObject();
m_flushedQueueJS = batchedBridge.getProperty(“flushedQueue”).asObject();
m_callFunctionReturnResultAndFlushedQueueJS = batchedBridge.getProperty(“callFunctionReturnResultAndFlushedQueue”).asObject();
});
}
至此,JS Bundle已经加载解析完成,进入MessageQueue.js开始执行。
2.4 绑定ReactContext与ReactRootView
JS Bundle加载完成以后,前面说的createReactContext()就执行完成了,然后开始执行setupReacContext()方法,绑定ReactContext与ReactRootView。 我们来看一下它的实现。
public class ReactInstanceManager {
private void setupReactContext(final ReactApplicationContext reactContext) {
//…
//执行Java Module的初始化
catalystInstance.initialize();
//通知ReactContext已经被创建爱女
mDevSupportManager.onNewReactContextCreated(reactContext);
//内存状态回调设置
mMemoryPressureRouter.addMemoryPressureListener(catalystInstance);
//复位生命周期
moveReactContextToCurrentLifecycleState();
ReactMarker.logMarker(ATTACH_MEASURED_ROOT_VIEWS_START);
synchronized (mAttachedRootViews) {
//将所有的ReactRootView与catalystInstance进行绑定
for (ReactRootView rootView : mAttachedRootViews) {
attachRootViewToInstance(rootView, catalystInstance);
}
}
//…
}
private void attachRootViewToInstance(
final ReactRootView rootView,
CatalystInstance catalystInstance) {
//…
UIManagerModule uiManagerModule = catalystInstance.getNativeModule(UIManagerModule.class);
//将ReactRootView作为根布局
final int rootTag = uiManagerModule.addRootView(rootView);
rootView.setRootViewTag(rootTag);
//执行JS的入口bundle页面
rootView.invokeJSEntryPoint();
//…
}
x
}
setupReactContext()方法主要完成每个ReactRootView与catalystInstance的绑定,绑定的过程主要做两件事情:
- 将ReactRootView作为根布局.
- 执行JS的入口bundle页面.
JS的页面入口我们可以设置mJSEntryPoint来自定义入口,如果不设置则是默认的入口AppRegistry。
private void defaultJSEntryPoint() {
//…
try {
//…
String jsAppModuleName = getJSModuleName();
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
} finally {
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}
}<