React Native源代码分析--Android客户端启动流程(从JS到Java)

上一篇文章讲到启动过程中,最终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


8557291-509c5b15ab3d30f3.jpg
启动过程中JS调用Java的过程

而且其中的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);
  }

所以最终会调用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->

转载于:https://www.jianshu.com/p/f3813379f76c

猜你喜欢

转载自blog.csdn.net/weixin_34129696/article/details/91270043