Allow installing JS binding via the RN Android bridge

Reviewed By: fkgozali

Differential Revision: D6979072

fbshipit-source-id: 8b4ac3769496a6a6fe3dd9ee2aac64b66604c413
This commit is contained in:
David Vacca 2018-02-14 11:26:39 -08:00 committed by Facebook Github Bot
parent ecc08adf49
commit db391a500c
5 changed files with 74 additions and 26 deletions

View File

@ -45,13 +45,13 @@ import com.facebook.debug.tags.ReactDebugOverlayTags;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.ThreadConfined; import com.facebook.infer.annotation.ThreadConfined;
import com.facebook.infer.annotation.ThreadSafe; import com.facebook.infer.annotation.ThreadSafe;
import com.facebook.react.bridge.BridgeListener;
import com.facebook.react.bridge.CatalystInstance; import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.CatalystInstanceImpl; import com.facebook.react.bridge.CatalystInstanceImpl;
import com.facebook.react.bridge.JSBundleLoader; import com.facebook.react.bridge.JSBundleLoader;
import com.facebook.react.bridge.JavaJSExecutor; import com.facebook.react.bridge.JavaJSExecutor;
import com.facebook.react.bridge.JavaScriptExecutor; import com.facebook.react.bridge.JavaScriptExecutor;
import com.facebook.react.bridge.JavaScriptExecutorFactory; import com.facebook.react.bridge.JavaScriptExecutorFactory;
import com.facebook.react.bridge.NativeArray;
import com.facebook.react.bridge.NativeModuleCallExceptionHandler; import com.facebook.react.bridge.NativeModuleCallExceptionHandler;
import com.facebook.react.bridge.NativeModuleRegistry; import com.facebook.react.bridge.NativeModuleRegistry;
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener; import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
@ -124,6 +124,7 @@ public class ReactInstanceManager {
*/ */
void onReactContextInitialized(ReactContext context); void onReactContextInitialized(ReactContext context);
} }
private final List<ReactRootView> mAttachedRootViews = Collections.synchronizedList( private final List<ReactRootView> mAttachedRootViews = Collections.synchronizedList(
new ArrayList<ReactRootView>()); new ArrayList<ReactRootView>());
@ -156,6 +157,7 @@ public class ReactInstanceManager {
private final @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler; private final @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private final boolean mLazyNativeModulesEnabled; private final boolean mLazyNativeModulesEnabled;
private final boolean mDelayViewManagerClassLoadsEnabled; private final boolean mDelayViewManagerClassLoadsEnabled;
private final @Nullable BridgeListener mBridgeListener;
private class ReactContextInitParams { private class ReactContextInitParams {
private final JavaScriptExecutorFactory mJsExecutorFactory; private final JavaScriptExecutorFactory mJsExecutorFactory;
@ -203,7 +205,8 @@ public class ReactInstanceManager {
boolean delayViewManagerClassLoadsEnabled, boolean delayViewManagerClassLoadsEnabled,
@Nullable DevBundleDownloadListener devBundleDownloadListener, @Nullable DevBundleDownloadListener devBundleDownloadListener,
int minNumShakes, int minNumShakes,
int minTimeLeftInFrameForNonBatchedOperationMs) { int minTimeLeftInFrameForNonBatchedOperationMs,
@Nullable BridgeListener bridgeListener) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.ctor()"); Log.d(ReactConstants.TAG, "ReactInstanceManager.ctor()");
initializeSoLoaderIfNecessary(applicationContext); initializeSoLoaderIfNecessary(applicationContext);
@ -252,6 +255,7 @@ public class ReactInstanceManager {
} }
mPackages.addAll(packages); mPackages.addAll(packages);
} }
mBridgeListener = bridgeListener;
// Instantiate ReactChoreographer in UI thread. // Instantiate ReactChoreographer in UI thread.
ReactChoreographer.initialize(); ReactChoreographer.initialize();
@ -1100,7 +1104,8 @@ public class ReactInstanceManager {
.setJSExecutor(jsExecutor) .setJSExecutor(jsExecutor)
.setRegistry(nativeModuleRegistry) .setRegistry(nativeModuleRegistry)
.setJSBundleLoader(jsBundleLoader) .setJSBundleLoader(jsBundleLoader)
.setNativeModuleCallExceptionHandler(exceptionHandler); .setNativeModuleCallExceptionHandler(exceptionHandler)
.setBridgeListener(mBridgeListener);
ReactMarker.logMarker(CREATE_CATALYST_INSTANCE_START); ReactMarker.logMarker(CREATE_CATALYST_INSTANCE_START);
// CREATE_CATALYST_INSTANCE_END is in JSCExecutor.cpp // CREATE_CATALYST_INSTANCE_END is in JSCExecutor.cpp

View File

@ -7,6 +7,8 @@ import static com.facebook.react.modules.systeminfo.AndroidInfoHelpers.getFriend
import android.app.Activity; import android.app.Activity;
import android.app.Application; import android.app.Application;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.BridgeListener;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JSBundleLoader; import com.facebook.react.bridge.JSBundleLoader;
import com.facebook.react.bridge.JSCJavaScriptExecutorFactory; import com.facebook.react.bridge.JSCJavaScriptExecutorFactory;
import com.facebook.react.bridge.JavaScriptExecutorFactory; import com.facebook.react.bridge.JavaScriptExecutorFactory;
@ -48,6 +50,7 @@ public class ReactInstanceManagerBuilder {
private @Nullable JavaScriptExecutorFactory mJavaScriptExecutorFactory; private @Nullable JavaScriptExecutorFactory mJavaScriptExecutorFactory;
private int mMinNumShakes = 1; private int mMinNumShakes = 1;
private int mMinTimeLeftInFrameForNonBatchedOperationMs = -1; private int mMinTimeLeftInFrameForNonBatchedOperationMs = -1;
private @Nullable BridgeListener mBridgeListener;
/* package protected */ ReactInstanceManagerBuilder() { /* package protected */ ReactInstanceManagerBuilder() {
} }
@ -62,6 +65,12 @@ public class ReactInstanceManagerBuilder {
return this; return this;
} }
public ReactInstanceManagerBuilder setBridgeListener(
@Nullable BridgeListener listener) {
mBridgeListener = listener;
return this;
}
/** /**
* Factory for desired implementation of JavaScriptExecutor. * Factory for desired implementation of JavaScriptExecutor.
*/ */
@ -280,6 +289,7 @@ public class ReactInstanceManagerBuilder {
mDelayViewManagerClassLoadsEnabled, mDelayViewManagerClassLoadsEnabled,
mDevBundleDownloadListener, mDevBundleDownloadListener,
mMinNumShakes, mMinNumShakes,
mMinTimeLeftInFrameForNonBatchedOperationMs); mMinTimeLeftInFrameForNonBatchedOperationMs,
mBridgeListener);
} }
} }

View File

@ -16,6 +16,7 @@ import java.util.List;
import android.app.Application; import android.app.Application;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.BridgeListener;
import com.facebook.react.bridge.JavaScriptExecutorFactory; import com.facebook.react.bridge.JavaScriptExecutorFactory;
import com.facebook.react.bridge.ReactMarker; import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.ReactMarkerConstants; import com.facebook.react.bridge.ReactMarkerConstants;
@ -76,6 +77,7 @@ public abstract class ReactNativeHost {
.setRedBoxHandler(getRedBoxHandler()) .setRedBoxHandler(getRedBoxHandler())
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory()) .setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
.setUIImplementationProvider(getUIImplementationProvider()) .setUIImplementationProvider(getUIImplementationProvider())
.setBridgeListener(getBridgeListener())
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE); .setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
for (ReactPackage reactPackage : getPackages()) { for (ReactPackage reactPackage : getPackages()) {
@ -122,6 +124,10 @@ public abstract class ReactNativeHost {
return new UIImplementationProvider(); return new UIImplementationProvider();
} }
protected @Nullable BridgeListener getBridgeListener() {
return null;
}
/** /**
* Returns the name of the main module. Determines the URL used to fetch the JS bundle * Returns the name of the main module. Determines the URL used to fetch the JS bundle
* from the packager server. It is only used when dev support is enabled. * from the packager server. It is only used when dev support is enabled.

View File

@ -0,0 +1,14 @@
package com.facebook.react.bridge;
/**
* Interface to listen to bridge events.
*/
public interface BridgeListener {
/**
* Called right after the RN Bridge is initialized
* @param catalystInstance {@link CatalystInstance} bridge
*/
void onBridgeStarted(CatalystInstance catalystInstance);
}

View File

@ -100,7 +100,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
final JavaScriptExecutor jsExecutor, final JavaScriptExecutor jsExecutor,
final NativeModuleRegistry nativeModuleRegistry, final NativeModuleRegistry nativeModuleRegistry,
final JSBundleLoader jsBundleLoader, final JSBundleLoader jsBundleLoader,
NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler) { NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler,
final BridgeListener bridgeListener) {
Log.d(ReactConstants.TAG, "Initializing React Xplat Bridge."); Log.d(ReactConstants.TAG, "Initializing React Xplat Bridge.");
mHybridData = initHybrid(); mHybridData = initHybrid();
@ -126,6 +127,9 @@ public class CatalystInstanceImpl implements CatalystInstance {
Log.d(ReactConstants.TAG, "Initializing React Xplat Bridge after initializeBridge"); Log.d(ReactConstants.TAG, "Initializing React Xplat Bridge after initializeBridge");
mJavaScriptContextHolder = new JavaScriptContextHolder(getJavaScriptContext()); mJavaScriptContextHolder = new JavaScriptContextHolder(getJavaScriptContext());
if (bridgeListener != null) {
bridgeListener.onBridgeStarted(this);
}
} }
private static class BridgeCallback implements ReactCallback { private static class BridgeCallback implements ReactCallback {
@ -134,8 +138,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
// and determine there's an inaccessible cycle. // and determine there's an inaccessible cycle.
private final WeakReference<CatalystInstanceImpl> mOuter; private final WeakReference<CatalystInstanceImpl> mOuter;
public BridgeCallback(CatalystInstanceImpl outer) { BridgeCallback(CatalystInstanceImpl outer) {
mOuter = new WeakReference<CatalystInstanceImpl>(outer); mOuter = new WeakReference<>(outer);
} }
@Override @Override
@ -553,6 +557,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
private @Nullable NativeModuleRegistry mRegistry; private @Nullable NativeModuleRegistry mRegistry;
private @Nullable JavaScriptExecutor mJSExecutor; private @Nullable JavaScriptExecutor mJSExecutor;
private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler; private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private @Nullable BridgeListener mBridgeListener;
public Builder setReactQueueConfigurationSpec( public Builder setReactQueueConfigurationSpec(
ReactQueueConfigurationSpec ReactQueueConfigurationSpec) { ReactQueueConfigurationSpec ReactQueueConfigurationSpec) {
@ -581,13 +587,20 @@ public class CatalystInstanceImpl implements CatalystInstance {
return this; return this;
} }
public Builder setBridgeListener(
BridgeListener listener) {
mBridgeListener = listener;
return this;
}
public CatalystInstanceImpl build() { public CatalystInstanceImpl build() {
return new CatalystInstanceImpl( return new CatalystInstanceImpl(
Assertions.assertNotNull(mReactQueueConfigurationSpec), Assertions.assertNotNull(mReactQueueConfigurationSpec),
Assertions.assertNotNull(mJSExecutor), Assertions.assertNotNull(mJSExecutor),
Assertions.assertNotNull(mRegistry), Assertions.assertNotNull(mRegistry),
Assertions.assertNotNull(mJSBundleLoader), Assertions.assertNotNull(mJSBundleLoader),
Assertions.assertNotNull(mNativeModuleCallExceptionHandler)); Assertions.assertNotNull(mNativeModuleCallExceptionHandler),
mBridgeListener);
} }
} }
} }