mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-28 20:25:33 +08:00
Expose way for native modules to modify JSC context
Reviewed By: svcscm Differential Revision: D2933197 fb-gh-sync-id: 32eb943ab341804343bbcadd29f0377fccf75de6 shipit-source-id: 32eb943ab341804343bbcadd29f0377fccf75de6
This commit is contained in:
committed by
facebook-github-bot-1
parent
46a8f1d8e0
commit
e5ba46c30d
@@ -16,6 +16,15 @@
|
|||||||
*/
|
*/
|
||||||
RCT_EXTERN NSString *const RCTJSCThreadName;
|
RCT_EXTERN NSString *const RCTJSCThreadName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This notification fires on the JS thread immediately after a `JSContext`
|
||||||
|
* is fully initialized, but before the JS bundle has been loaded. The object
|
||||||
|
* of this notification is the `JSContext`. Native modules should listen for
|
||||||
|
* notification only if they need to install custom functionality into the
|
||||||
|
* context. Note that this notification won't fire when debugging in Chrome.
|
||||||
|
*/
|
||||||
|
RCT_EXTERN NSString *const RCTJavaScriptContextCreatedNotification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses a JavaScriptCore context as the execution engine.
|
* Uses a JavaScriptCore context as the execution engine.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
NSString *const RCTJSCThreadName = @"com.facebook.React.JavaScript";
|
NSString *const RCTJSCThreadName = @"com.facebook.React.JavaScript";
|
||||||
|
|
||||||
|
NSString *const RCTJavaScriptContextCreatedNotification = @"RCTJavaScriptContextCreatedNotification";
|
||||||
|
|
||||||
static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabled";
|
static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabled";
|
||||||
|
|
||||||
@interface RCTJavaScriptContext : NSObject <RCTInvalidating>
|
@interface RCTJavaScriptContext : NSObject <RCTInvalidating>
|
||||||
@@ -332,7 +334,16 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
[self executeBlockOnJavaScriptQueue:^{
|
[self executeBlockOnJavaScriptQueue:^{
|
||||||
RCTInstallJSCProfiler(_bridge, self.context.ctx);
|
RCTJSCExecutor *strongSelf = weakSelf;
|
||||||
|
if (!strongSelf.valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSContext *context = strongSelf.context.context;
|
||||||
|
RCTInstallJSCProfiler(_bridge, context.JSGlobalContextRef);
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptContextCreatedNotification
|
||||||
|
object:context];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
for (NSString *event in @[RCTProfileDidStartProfiling, RCTProfileDidEndProfiling]) {
|
for (NSString *event in @[RCTProfileDidStartProfiling, RCTProfileDidEndProfiling]) {
|
||||||
|
|||||||
@@ -332,6 +332,11 @@ public abstract class BaseJavaModule implements NativeModule {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReactBridgeInitialized(ReactBridge bridge) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCatalystInstanceDestroy() {
|
public void onCatalystInstanceDestroy() {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
|||||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mJavaRegistry.notifyReactBridgeInitialized(bridge);
|
||||||
return bridge;
|
return bridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,15 @@ public interface NativeModule {
|
|||||||
*/
|
*/
|
||||||
boolean canOverrideExistingModule();
|
boolean canOverrideExistingModule();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on the JS thread after a ReactBridge has been created. This is useful for native modules
|
||||||
|
* that need to do any setup before the JS bundle has been loaded. An example of this would be
|
||||||
|
* installing custom functionality into the JavaScriptCore context.
|
||||||
|
*
|
||||||
|
* @param bridge the ReactBridge instance that has just been created
|
||||||
|
*/
|
||||||
|
void onReactBridgeInitialized(ReactBridge bridge);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before {CatalystInstance#onHostDestroy}
|
* Called before {CatalystInstance#onHostDestroy}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -114,6 +114,19 @@ public class NativeModuleRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ void notifyReactBridgeInitialized(ReactBridge bridge) {
|
||||||
|
Systrace.beginSection(
|
||||||
|
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||||
|
"NativeModuleRegistry_notifyReactBridgeInitialized");
|
||||||
|
try {
|
||||||
|
for (NativeModule nativeModule : mModuleInstances.values()) {
|
||||||
|
nativeModule.onReactBridgeInitialized(bridge);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onBatchComplete() {
|
public void onBatchComplete() {
|
||||||
for (int i = 0; i < mBatchCompleteListenerModules.size(); i++) {
|
for (int i = 0; i < mBatchCompleteListenerModules.size(); i++) {
|
||||||
mBatchCompleteListenerModules.get(i).onBatchComplete();
|
mBatchCompleteListenerModules.get(i).onBatchComplete();
|
||||||
|
|||||||
@@ -87,4 +87,13 @@ public class ReactBridge extends Countable {
|
|||||||
public native void stopProfiler(String title, String filename);
|
public native void stopProfiler(String title, String filename);
|
||||||
private native void handleMemoryPressureModerate();
|
private native void handleMemoryPressureModerate();
|
||||||
private native void handleMemoryPressureCritical();
|
private native void handleMemoryPressureCritical();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return a long representing the underlying JSGlobalContextRef pointer or
|
||||||
|
* 0 (representing NULL) when in Chrome debug mode, and is only useful if passed back through
|
||||||
|
* the JNI to native code that will use it with the JavaScriptCore C API.
|
||||||
|
* **WARNING:** This method is *experimental* and should only be used when no other option is
|
||||||
|
* available. It will likely change in a future release!
|
||||||
|
*/
|
||||||
|
public native long getJavaScriptContextNativePtrExperimental();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ void Bridge::setGlobalVariable(const std::string& propName, const std::string& j
|
|||||||
m_mainExecutor->setGlobalVariable(propName, jsonValue);
|
m_mainExecutor->setGlobalVariable(propName, jsonValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* Bridge::getJavaScriptContext() {
|
||||||
|
return m_mainExecutor->getJavaScriptContext();
|
||||||
|
}
|
||||||
|
|
||||||
bool Bridge::supportsProfiling() {
|
bool Bridge::supportsProfiling() {
|
||||||
return m_mainExecutor->supportsProfiling();
|
return m_mainExecutor->supportsProfiling();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
const std::string& startupCode,
|
const std::string& startupCode,
|
||||||
const std::string& sourceURL);
|
const std::string& sourceURL);
|
||||||
void setGlobalVariable(const std::string& propName, const std::string& jsonValue);
|
void setGlobalVariable(const std::string& propName, const std::string& jsonValue);
|
||||||
|
void* getJavaScriptContext();
|
||||||
bool supportsProfiling();
|
bool supportsProfiling();
|
||||||
void startProfiler(const std::string& title);
|
void startProfiler(const std::string& title);
|
||||||
void stopProfiler(const std::string& title, const std::string& filename);
|
void stopProfiler(const std::string& title, const std::string& filename);
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ public:
|
|||||||
virtual void setGlobalVariable(
|
virtual void setGlobalVariable(
|
||||||
const std::string& propName,
|
const std::string& propName,
|
||||||
const std::string& jsonValue) = 0;
|
const std::string& jsonValue) = 0;
|
||||||
|
virtual void* getJavaScriptContext() {
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
virtual bool supportsProfiling() {
|
virtual bool supportsProfiling() {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -198,6 +198,10 @@ void JSCExecutor::setGlobalVariable(const std::string& propName, const std::stri
|
|||||||
JSObjectSetProperty(m_context, globalObject, jsPropertyName, valueToInject, 0, NULL);
|
JSObjectSetProperty(m_context, globalObject, jsPropertyName, valueToInject, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* JSCExecutor::getJavaScriptContext() {
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
bool JSCExecutor::supportsProfiling() {
|
bool JSCExecutor::supportsProfiling() {
|
||||||
#ifdef WITH_FBSYSTRACE
|
#ifdef WITH_FBSYSTRACE
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
virtual void setGlobalVariable(
|
virtual void setGlobalVariable(
|
||||||
const std::string& propName,
|
const std::string& propName,
|
||||||
const std::string& jsonValue) override;
|
const std::string& jsonValue) override;
|
||||||
|
virtual void* getJavaScriptContext() override;
|
||||||
virtual bool supportsProfiling() override;
|
virtual bool supportsProfiling() override;
|
||||||
virtual void startProfiler(const std::string &titleString) override;
|
virtual void startProfiler(const std::string &titleString) override;
|
||||||
virtual void stopProfiler(const std::string &titleString, const std::string &filename) override;
|
virtual void stopProfiler(const std::string &titleString, const std::string &filename) override;
|
||||||
|
|||||||
@@ -760,6 +760,11 @@ static void setGlobalVariable(JNIEnv* env, jobject obj, jstring propName, jstrin
|
|||||||
bridge->setGlobalVariable(fromJString(env, propName), fromJString(env, jsonValue));
|
bridge->setGlobalVariable(fromJString(env, propName), fromJString(env, jsonValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jlong getJavaScriptContext(JNIEnv *env, jobject obj) {
|
||||||
|
auto bridge = extractRefPtr<CountableBridge>(env, obj);
|
||||||
|
return (uintptr_t) bridge->getJavaScriptContext();
|
||||||
|
}
|
||||||
|
|
||||||
static jboolean supportsProfiling(JNIEnv* env, jobject obj) {
|
static jboolean supportsProfiling(JNIEnv* env, jobject obj) {
|
||||||
auto bridge = extractRefPtr<CountableBridge>(env, obj);
|
auto bridge = extractRefPtr<CountableBridge>(env, obj);
|
||||||
return bridge->supportsProfiling() ? JNI_TRUE : JNI_FALSE;
|
return bridge->supportsProfiling() ? JNI_TRUE : JNI_FALSE;
|
||||||
@@ -944,7 +949,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||||||
makeNativeMethod("stopProfiler", bridge::stopProfiler),
|
makeNativeMethod("stopProfiler", bridge::stopProfiler),
|
||||||
makeNativeMethod("handleMemoryPressureModerate", bridge::handleMemoryPressureModerate),
|
makeNativeMethod("handleMemoryPressureModerate", bridge::handleMemoryPressureModerate),
|
||||||
makeNativeMethod("handleMemoryPressureCritical", bridge::handleMemoryPressureCritical),
|
makeNativeMethod("handleMemoryPressureCritical", bridge::handleMemoryPressureCritical),
|
||||||
|
makeNativeMethod("getJavaScriptContextNativePtrExperimental", bridge::getJavaScriptContext),
|
||||||
});
|
});
|
||||||
|
|
||||||
jclass nativeRunnableClass = env->FindClass("com/facebook/react/bridge/queue/NativeRunnableDeprecated");
|
jclass nativeRunnableClass = env->FindClass("com/facebook/react/bridge/queue/NativeRunnableDeprecated");
|
||||||
|
|||||||
Reference in New Issue
Block a user