Allow reactinstancemanager to set an initialization function

Reviewed By: javache

Differential Revision: D5227811

fbshipit-source-id: e7868481de2a8799af5d6a6bcad26369d054b35e
This commit is contained in:
Kathy Gray
2017-08-14 06:50:30 -07:00
committed by Facebook Github Bot
parent 6783694158
commit 84e80eb781
4 changed files with 70 additions and 25 deletions

View File

@@ -55,6 +55,7 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.ReactMarkerConstants;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.NativeArray;
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.common.ReactConstants;
@@ -105,6 +106,8 @@ import javax.annotation.Nullable;
@ThreadSafe
public class ReactInstanceManager {
private static final String TAG = ReactInstanceManager.class.getSimpleName();
/**
* Listener interface for react instance events.
*/
@@ -127,6 +130,7 @@ public class ReactInstanceManager {
private final @Nullable JSBundleLoader mBundleLoader; /* path to JS bundle on file system */
private final @Nullable String mJSMainModulePath; /* path to JS bundle root on packager server */
private final List<ReactPackage> mPackages;
private final List<CatalystInstanceImpl.PendingJSCall> mInitFunctions;
private final DevSupportManager mDevSupportManager;
private final boolean mUseDeveloperSupport;
private final @Nullable NotThreadSafeBridgeIdleDebugListener mBridgeIdleDebugListener;
@@ -232,6 +236,7 @@ public class ReactInstanceManager {
mBundleLoader = bundleLoader;
mJSMainModulePath = jsMainModulePath;
mPackages = new ArrayList<>();
mInitFunctions = new ArrayList<>();
mUseDeveloperSupport = useDeveloperSupport;
mDevSupportManager = DevSupportManagerFactory.create(
applicationContext,
@@ -351,11 +356,33 @@ public class ReactInstanceManager {
}
/**
* Recreate the react application and context. This should be called if configuration has
* changed or the developer has requested the app to be reloaded. It should only be called after
* an initial call to createReactContextInBackground.
* If the JavaScript bundle for this app requires initialization as part of bridge start up,
* register a function using its @param module and @param method and optional arguments.
*/
public void registerInitFunction(String module, String method, @Nullable NativeArray arguments) {
CatalystInstanceImpl.PendingJSCall init =
new CatalystInstanceImpl.PendingJSCall(module, method, arguments);
synchronized (this) {
mInitFunctions.add(init);
}
ReactContext context = getCurrentReactContext();
CatalystInstance catalystInstance = context == null ? null : context.getCatalystInstance();
if (catalystInstance == null) {
return;
} else {
// CatalystInstance is only visible after running jsBundle, so these will be put on the native
// JS queue
// TODO T20546472 remove cast when catalystInstance and InstanceImpl are renamed/merged
((CatalystInstanceImpl) catalystInstance).callFunction(init);
}
}
/**
* Recreate the react application and context. This should be called if configuration has changed
* or the developer has requested the app to be reloaded. It should only be called after an
* initial call to createReactContextInBackground.
*
* Called from UI thread.
* <p>Called from UI thread.
*/
@ThreadConfined(UI)
public void recreateReactContextInBackground() {
@@ -995,10 +1022,19 @@ public class ReactInstanceManager {
if (Systrace.isTracing(TRACE_TAG_REACT_APPS | TRACE_TAG_REACT_JSC_CALLS)) {
catalystInstance.setGlobalVariable("__RCTProfileIsProfiling", "true");
}
catalystInstance.runJSBundle();
// Transitions functions in the minitFunctions list to catalystInstance, to run after the bundle
// TODO T20546472
if (!mInitFunctions.isEmpty()) {
for (CatalystInstanceImpl.PendingJSCall function : mInitFunctions) {
((CatalystInstanceImpl) catalystInstance).callFunction(function);
}
}
ReactMarker.logMarker(ReactMarkerConstants.PRE_RUN_JS_BUNDLE_START);
reactContext.initializeWithInstance(catalystInstance);
ReactMarker.logMarker(ReactMarkerConstants.PRE_RUN_JS_BUNDLE_START);
catalystInstance.runJSBundle();
return reactContext;
}