上一篇文章讲到启动过程中,最终Java层调用了JS层的AppRegistry.js的runApplication()方法来进行JS层的启动工作。
我们看一下runApplication()的整个调用过程:
runApplication()-> require('ReactNative').render(renderable, rootTag);-> ReactNativeRenderer-dev.render()-> updateContainer(element, root, null, callback);-> updateContainerAtExpirationTime->scheduleRootUpdate()-> scheduleWork()-> requestWork
()-> performSyncWork()-> performWork()-> performWorkOnRoot()-> renderRoot()->workLoop()-> performUnitOfWork()-> completeUnitOfWork()-> completeWork()-> createTextInstance()-> UIManager.createView
而且其中的UIManager来自于const {UIManager} = NativeModules;而NativeModules来自于 NativeModules = global.nativeModuleProxy;而在上一篇文章中我们说过,在void JSIExecutor::loadApplicationScript方法中,将该方法从C++层注入到了JS层中,代码如下:
void JSIExecutor::loadApplicationScript(
std::unique_ptr script,
std::string sourceURL) {
SystraceSection s("JSIExecutor::loadApplicationScript");
// TODO: check for and use precompiled HBC
runtime_->global().setProperty(
*runtime_,
"nativeModuleProxy",
Object::createFromHostObject(
*runtime_, std::make_shared(*this)));
runtime_->global().setProperty(
*runtime_,
"nativeFlushQueueImmediate",
Function::createFromHostFunction(
*runtime_,
PropNameID::forAscii(*runtime_, "nativeFlushQueueImmediate"),
1,
[this](
jsi::Runtime&,
const jsi::Value&,
const jsi::Value* args,
size_t count) {
if (count != 1) {
throw std::invalid_argument(
"nativeFlushQueueImmediate arg count must be 1");
}
callNativeModules(args[0], false);
return Value::undefined();
}));
runtime_->global().setProperty(
*runtime_,
"nativeCallSyncHook",
Function::createFromHostFunction(
*runtime_,
PropNameID::forAscii(*runtime_, "nativeCallSyncHook"),
1,
[this](
jsi::Runtime&,
const jsi::Value&,
const jsi::Value* args,
size_t count) { return nativeCallSyncHook(args, count); }));
if (logger_) {
// Only inject the logging function if it was supplied by the caller.
runtime_->global().setProperty(
*runtime_,
"nativeLoggingHook",
Function::createFromHostFunction(
*runtime_,
PropNameID::forAscii(*runtime_, "nativeLoggingHook"),
2,
[this](
jsi::Runtime&,
const jsi::Value&,
const jsi::Value* args,
size_t count) {
if (count != 2) {
throw std::invalid_argument(
"nativeLoggingHook takes 2 arguments");
}
logger_(
args[0].asString(*runtime_).utf8(*runtime_),
folly::to(args[1].asNumber()));
return Value::undefined();
}));
}
if (runtimeInstaller_) {
runtimeInstaller_(*runtime_);
}
bool hasLogger(ReactMarker::logTaggedMarker);
std::string scriptName = simpleBasename(sourceURL);
if (hasLogger) {
ReactMarker::logTaggedMarker(
ReactMarker::RUN_JS_BUNDLE_START, scriptName.c_str());
}
runtime_->evaluateJavaScript(
std::make_unique(std::move(script)), sourceURL);
flush();
if (hasLogger) {
ReactMarker::logMarker(ReactMarker::CREATE_REACT_CONTEXT_STOP);
ReactMarker::logTaggedMarker(
ReactMarker::RUN_JS_BUNDLE_STOP, scriptName.c_str());
}
}
他会调用executor_.nativeModules_.getModule(rt, 'UIManager');
JSINativeModules::JSINativeModules(
std::shared_ptr moduleRegistry)
: m_moduleRegistry(std::move(moduleRegistry)) {}
Value JSINativeModules::getModule(Runtime& rt, const PropNameID& name) {
if (!m_moduleRegistry) {
return nullptr;
}
std::string moduleName = name.utf8(rt);
const auto it = m_objects.find(moduleName);
if (it != m_objects.end()) {
return Value(rt, it->second);
}
auto module = createModule(rt, moduleName);
if (!module.hasValue()) {
// Allow lookup to continue in the objects own properties, which allows for
// overrides of NativeModules
return nullptr;
}
auto result =
m_objects.emplace(std::move(moduleName), std::move(*module)).first;
return Value(rt, result->second);
}
folly::Optional
在NativeModule.js中global.__fbGenNativeModule = genModule;因此上面的方法会调用genModule方法。genModule -> genMethod-> BatchedBridge.enqueueNativeCall-> global.nativeFlushQueueImmediate(this.queue)->JSIExecutor::callNativeModules-> ModuleRegistry->callNativeMethod(call.moduleId, call.methodId, std::move(call.arguments), call.callId);->modules[moduleId]->invoke(methodId, std::move(params), callId);->JavaNativeModule::invoke
void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] {
static auto invokeMethod = wrapper_->getClass()->getMethod("invoke");
#ifdef WITH_FBSYSTRACE
if (callId != -1) {
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
}
#endif
invokeMethod(
wrapper_,
static_cast(reactMethodId),
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
});
}
接着会调用到Java层中,通过反射调用ReactContextBaseJavaModule中的代码
public void invoke(int methodId, ReadableNativeArray parameters) {
if (mMethods == null || methodId >= mMethods.size()) {
return;
}
mMethods.get(methodId).invoke(mJSInstance, parameters);
}
所以最终会调用UIManagerModule.createView()->UIImplementation.createView()->handleCreateView()->NativeViewHierarchyOptimizer. handleCreateView()->mUIViewOperationQueue.enqueueCreateView->mUIViewOperationQueue.CreateViewOperation->mNativeViewHierarchyManager.createView()->viewManager.createView()
最终会调用各个子module的createViewInstance(),这样view就被创建出来了。
OnBatchCompleteListener.onBatchComplete()->mUIImplementation.dispatchViewUpdates(batchId);->mOperationsQueue.dispatchViewUpdates->