React Native Client source code analysis --Android start the process (from JS to Java)

Previous article talked about the boot process, the final layer of Java called runApplication AppRegistry.js of JS layer () methods to start the work of JS layer.
We look runApplication () calls the whole process:
. RunApplication () -> The require ( 'ReactNative') the render (Renderable, rootTag); -> ReactNativeRenderer-dev.render () -> the updateContainer (Element, root, null, callback ); -> updateContainerAtExpirationTime-> scheduleRootUpdate () -> scheduleWork () -> requestWork
() -> performSyncWork () -> performWork () -> performWorkOnRoot () -> renderRoot () -> workLoop () -> performUnitOfWork () -> completeUnitOfWork () -> completeWork () -> createTextInstance () -> UIManager.createView


8557291-509c5b15ab3d30f3.jpg
JS call Java startup process

而且其中的UIManager来自于const {UIManager} = NativeModules;而NativeModules来自于 NativeModules = global.nativeModuleProxy;而在上一篇文章中我们说过,在void JSIExecutor::loadApplicationScript方法中,将该方法从C++层注入到了JS层中,代码如下:

void JSIExecutor::loadApplicationScript(
    std::unique_ptr<const JSBigString> 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<NativeModuleProxy>(*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<unsigned int>(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<BigStringBuffer>(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> 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<Object> JSINativeModules::createModule(
    Runtime& rt,
    const std::string& name) {
  bool hasLogger(ReactMarker::logTaggedMarker);
  if (hasLogger) {
    ReactMarker::logTaggedMarker(
        ReactMarker::NATIVE_MODULE_SETUP_START, name.c_str());
  }

  if (!m_genNativeModuleJS) {
    m_genNativeModuleJS =
        rt.global().getPropertyAsFunction(rt, "__fbGenNativeModule");
  }

  auto result = m_moduleRegistry->getConfig(name);
  if (!result.hasValue()) {
    return folly::none;
  }

  Value moduleInfo = m_genNativeModuleJS->call(
      rt,
      valueFromDynamic(rt, result->config),
      static_cast<double>(result->index));
  CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null";

  folly::Optional<Object> module(
      moduleInfo.asObject(rt).getPropertyAsObject(rt, "module"));

  if (hasLogger) {
    ReactMarker::logTaggedMarker(
        ReactMarker::NATIVE_MODULE_SETUP_STOP, name.c_str());
  }

  return module;
}

在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<void(jint, ReadableNativeArray::javaobject)>("invoke");
    #ifdef WITH_FBSYSTRACE
    if (callId != -1) {
      fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
    }
    #endif
    invokeMethod(
      wrapper_,
      static_cast<jint>(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);
  }

So eventually calls UIManagerModule.createView () -> UIImplementation.createView () -> handleCreateView () -> NativeViewHierarchyOptimizer handleCreateView () -.> MUIViewOperationQueue.enqueueCreateView-> mUIViewOperationQueue.CreateViewOperation-> mNativeViewHierarchyManager.createView () -> viewManager.createView ()
eventually calls each sub-module of createViewInstance (), this view is created out.
OnBatchCompleteListener.onBatchComplete () -> mUIImplementation.dispatchViewUpdates (batchId ); -> mOperationsQueue.dispatchViewUpdates->

Reproduced in: https: //www.jianshu.com/p/f3813379f76c

Guess you like

Origin blog.csdn.net/weixin_34129696/article/details/91270043