mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Support ModuleHolder-based lazy init of C++ modules with C++ bridge on android
Reviewed By: AaaChiuuu Differential Revision: D4614479 fbshipit-source-id: 109ac34b8688f0113675e4a4479d1ddcc6169ed4
This commit is contained in:
committed by
Facebook Github Bot
parent
6410e256c5
commit
e622d51e20
@@ -110,7 +110,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
final JavaScriptModuleRegistry jsModuleRegistry,
|
||||
final JSBundleLoader jsBundleLoader,
|
||||
NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler) {
|
||||
FLog.d(ReactConstants.TAG, "Initializing React Xplat Bridge.");
|
||||
FLog.w(ReactConstants.TAG, "Initializing React Xplat Bridge.");
|
||||
mHybridData = initHybrid();
|
||||
|
||||
mReactQueueConfiguration = ReactQueueConfigurationImpl.create(
|
||||
@@ -123,6 +123,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
|
||||
mTraceListener = new JSProfilerTraceListener(this);
|
||||
|
||||
FLog.w(ReactConstants.TAG, "Initializing React Xplat Bridge before initializeBridge");
|
||||
initializeBridge(
|
||||
new BridgeCallback(this),
|
||||
jsExecutor,
|
||||
@@ -130,6 +131,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
mReactQueueConfiguration.getNativeModulesQueueThread(),
|
||||
mJavaRegistry.getJavaModules(this),
|
||||
mJavaRegistry.getCxxModules());
|
||||
FLog.w(ReactConstants.TAG, "Initializing React Xplat Bridge after initializeBridge");
|
||||
mMainExecutorToken = getMainExecutorToken();
|
||||
}
|
||||
|
||||
@@ -182,7 +184,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
MessageQueueThread jsQueue,
|
||||
MessageQueueThread moduleQueue,
|
||||
Collection<JavaModuleWrapper> javaModules,
|
||||
Collection<CxxModuleWrapper> cxxModules);
|
||||
Collection<ModuleHolder> cxxModules);
|
||||
|
||||
/**
|
||||
* This API is used in situations where the JS bundle is being executed not on
|
||||
|
||||
@@ -53,12 +53,12 @@ public class NativeModuleRegistry {
|
||||
return javaModules;
|
||||
}
|
||||
|
||||
/* package */ Collection<CxxModuleWrapper> getCxxModules() {
|
||||
ArrayList<CxxModuleWrapper> cxxModules = new ArrayList<>();
|
||||
/* package */ Collection<ModuleHolder> getCxxModules() {
|
||||
ArrayList<ModuleHolder> cxxModules = new ArrayList<>();
|
||||
for (Map.Entry<Class<? extends NativeModule>, ModuleHolder> entry : mModules.entrySet()) {
|
||||
Class<?> type = entry.getKey();
|
||||
if (CxxModuleWrapper.class.isAssignableFrom(type)) {
|
||||
cxxModules.add((CxxModuleWrapper) entry.getValue().getModule());
|
||||
cxxModules.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
return cxxModules;
|
||||
|
||||
@@ -15,6 +15,7 @@ LOCAL_SRC_FILES := \
|
||||
JSLogging.cpp \
|
||||
JniJSModulesUnbundle.cpp \
|
||||
MethodInvoker.cpp \
|
||||
ModuleRegistryBuilder.cpp \
|
||||
NativeArray.cpp \
|
||||
NativeCommon.cpp \
|
||||
NativeMap.cpp \
|
||||
|
||||
@@ -6,6 +6,7 @@ EXPORTED_HEADERS = [
|
||||
"JExecutorToken.h",
|
||||
"JSLoader.h",
|
||||
"MethodInvoker.h",
|
||||
"ModuleRegistryBuilder.h",
|
||||
"NativeArray.h",
|
||||
"NativeCommon.h",
|
||||
"NativeMap.h",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <cxxreact/ModuleRegistry.h>
|
||||
#include <cxxreact/CxxNativeModule.h>
|
||||
|
||||
#include "CxxModuleWrapper.h"
|
||||
#include "JavaScriptExecutorHolder.h"
|
||||
#include "JniJSModulesUnbundle.h"
|
||||
#include "JNativeRunnable.h"
|
||||
@@ -128,21 +129,10 @@ void CatalystInstanceImpl::initializeBridge(
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules) {
|
||||
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject> cxxModules) {
|
||||
// TODO mhorowitz: how to assert here?
|
||||
// Assertions.assertCondition(mBridge == null, "initializeBridge should be called once");
|
||||
|
||||
std::vector<std::unique_ptr<NativeModule>> modules;
|
||||
std::weak_ptr<Instance> winstance(instance_);
|
||||
for (const auto& jm : *javaModules) {
|
||||
modules.emplace_back(folly::make_unique<JavaNativeModule>(winstance, jm));
|
||||
}
|
||||
for (const auto& cm : *cxxModules) {
|
||||
modules.emplace_back(
|
||||
folly::make_unique<CxxNativeModule>(winstance, std::move(cthis(cm)->getModule())));
|
||||
}
|
||||
auto moduleRegistry = std::make_shared<ModuleRegistry>(std::move(modules));
|
||||
|
||||
// This used to be:
|
||||
//
|
||||
// Java CatalystInstanceImpl -> C++ CatalystInstanceImpl -> Bridge -> Bridge::Callback
|
||||
@@ -163,7 +153,8 @@ void CatalystInstanceImpl::initializeBridge(
|
||||
jseh->getExecutorFactory(),
|
||||
folly::make_unique<JMessageQueueThread>(jsQueue),
|
||||
folly::make_unique<JMessageQueueThread>(moduleQueue),
|
||||
moduleRegistry);
|
||||
buildModuleRegistry(std::weak_ptr<Instance>(instance_),
|
||||
javaModules, cxxModules));
|
||||
}
|
||||
|
||||
void CatalystInstanceImpl::jniSetSourceURL(const std::string& sourceURL) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "JMessageQueueThread.h"
|
||||
#include "JSLoader.h"
|
||||
#include "JavaModuleWrapper.h"
|
||||
#include "ModuleRegistryBuilder.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -48,7 +49,7 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules);
|
||||
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject> cxxModules);
|
||||
|
||||
/**
|
||||
* Sets the source URL of the underlying bridge without loading any JS code.
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class CxxModuleWrapper : public jni::HybridClass<CxxModuleWrapper> {
|
||||
struct JNativeModule : jni::JavaClass<JNativeModule> {
|
||||
constexpr static const char *const kJavaDescriptor =
|
||||
"Lcom/facebook/react/bridge/NativeModule;";
|
||||
};
|
||||
|
||||
class CxxModuleWrapper :
|
||||
public jni::HybridClass<CxxModuleWrapper, JNativeModule> {
|
||||
public:
|
||||
constexpr static const char *const kJavaDescriptor =
|
||||
"Lcom/facebook/react/cxxbridge/CxxModuleWrapper;";
|
||||
|
||||
@@ -27,6 +27,8 @@ struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/cxxbridge/JavaModuleWrapper;";
|
||||
|
||||
jni::local_ref<JBaseJavaModule::javaobject> getModule() {
|
||||
// This is the call which causes a lazy Java module to actually be
|
||||
// created.
|
||||
static auto getModule = javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>("getModule");
|
||||
return getModule(self());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "ModuleRegistryBuilder.h"
|
||||
|
||||
#include <cxxreact/CxxNativeModule.h>
|
||||
#include <folly/Memory.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::string ModuleHolder::getName() const {
|
||||
static auto method = getClass()->getMethod<jstring()>("getName");
|
||||
return method(self())->toStdString();
|
||||
}
|
||||
|
||||
xplat::module::CxxModule::Provider ModuleHolder::getProvider() const {
|
||||
return [self=jni::make_global(self())] {
|
||||
static auto method =
|
||||
ModuleHolder::javaClassStatic()->getMethod<JNativeModule::javaobject()>(
|
||||
"getModule");
|
||||
// This is the call which uses the lazy Java Provider to instantiate the
|
||||
// Java CxxModuleWrapper which contains the CxxModule.
|
||||
auto module = method(self);
|
||||
CHECK(module->isInstanceOf(CxxModuleWrapper::javaClassStatic()))
|
||||
<< "module isn't a C++ module";
|
||||
auto cxxModule = jni::static_ref_cast<CxxModuleWrapper::javaobject>(module);
|
||||
// Then, we grab the CxxModule from the wrapper, which is no longer needed.
|
||||
return cxxModule->cthis()->getModule();
|
||||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<ModuleRegistry> buildModuleRegistry(
|
||||
std::weak_ptr<Instance> winstance,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject> cxxModules) {
|
||||
std::vector<std::unique_ptr<NativeModule>> modules;
|
||||
for (const auto& jm : *javaModules) {
|
||||
modules.emplace_back(folly::make_unique<JavaNativeModule>(winstance, jm));
|
||||
}
|
||||
for (const auto& cm : *cxxModules) {
|
||||
modules.emplace_back(
|
||||
folly::make_unique<CxxNativeModule>(winstance, cm->getName(), cm->getProvider()));
|
||||
}
|
||||
if (modules.empty()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return folly::make_unique<ModuleRegistry>(std::move(modules));
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <cxxreact/CxxModule.h>
|
||||
#include <cxxreact/ModuleRegistry.h>
|
||||
#include <fb/fbjni.h>
|
||||
|
||||
#include "CxxModuleWrapper.h"
|
||||
#include "JavaModuleWrapper.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ModuleHolder : public jni::JavaClass<ModuleHolder> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor =
|
||||
"Lcom/facebook/react/cxxbridge/ModuleHolder;";
|
||||
|
||||
std::string getName() const;
|
||||
xplat::module::CxxModule::Provider getProvider() const;
|
||||
};
|
||||
|
||||
std::unique_ptr<ModuleRegistry> buildModuleRegistry(
|
||||
std::weak_ptr<Instance> winstance,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject> cxxModules);
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user