Add UIImplementationProvider and allow overriding it in AbstractReactActivity

Summary: public UIImplementationProvider allows plugging in an alternative UIImplementation. A follow up diff adds a toggle under FB Dev Settings and uses this class to control an implementation. This allows us experimenting with other ways of generating UI hierarchy from JavaScript components.

Reviewed By: astreet

Differential Revision: D2554774

fb-gh-sync-id: 6574a893020e3519bd2ab00b9620a6dbdfaed595
This commit is contained in:
Denis Koroskin 2015-11-29 22:24:36 -08:00 committed by facebook-github-bot-7
parent e8e7a2db57
commit 3dca8cf9fd
5 changed files with 57 additions and 16 deletions

View File

@ -28,7 +28,7 @@ import com.facebook.react.modules.debug.SourceCodeModule;
import com.facebook.react.modules.systeminfo.AndroidInfoModule; import com.facebook.react.modules.systeminfo.AndroidInfoModule;
import com.facebook.react.uimanager.AppRegistry; import com.facebook.react.uimanager.AppRegistry;
import com.facebook.react.uimanager.ReactNative; import com.facebook.react.uimanager.ReactNative;
import com.facebook.react.uimanager.UIImplementation; import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.debug.DebugComponentOwnershipModule; import com.facebook.react.uimanager.debug.DebugComponentOwnershipModule;
@ -44,12 +44,15 @@ import com.facebook.systrace.Systrace;
private final ReactInstanceManager mReactInstanceManager; private final ReactInstanceManager mReactInstanceManager;
private final DefaultHardwareBackBtnHandler mHardwareBackBtnHandler; private final DefaultHardwareBackBtnHandler mHardwareBackBtnHandler;
private final UIImplementationProvider mUIImplementationProvider;
CoreModulesPackage( CoreModulesPackage(
ReactInstanceManager reactInstanceManager, ReactInstanceManager reactInstanceManager,
DefaultHardwareBackBtnHandler hardwareBackBtnHandler) { DefaultHardwareBackBtnHandler hardwareBackBtnHandler,
UIImplementationProvider uiImplementationProvider) {
mReactInstanceManager = reactInstanceManager; mReactInstanceManager = reactInstanceManager;
mHardwareBackBtnHandler = hardwareBackBtnHandler; mHardwareBackBtnHandler = hardwareBackBtnHandler;
mUIImplementationProvider = uiImplementationProvider;
} }
@Override @Override
@ -63,7 +66,9 @@ import com.facebook.systrace.Systrace;
uiManagerModule = new UIManagerModule( uiManagerModule = new UIManagerModule(
catalystApplicationContext, catalystApplicationContext,
viewManagersList, viewManagersList,
new UIImplementation(catalystApplicationContext, viewManagersList)); mUIImplementationProvider.createUIImplementation(
catalystApplicationContext,
viewManagersList));
} finally { } finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
} }

View File

@ -25,6 +25,7 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.devsupport.DevSupportManager; import com.facebook.react.devsupport.DevSupportManager;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
/** /**
@ -140,13 +141,23 @@ public abstract class ReactInstanceManager {
protected @Nullable Application mApplication; protected @Nullable Application mApplication;
protected boolean mUseDeveloperSupport; protected boolean mUseDeveloperSupport;
protected @Nullable LifecycleState mInitialLifecycleState; protected @Nullable LifecycleState mInitialLifecycleState;
protected @Nullable UIImplementationProvider mUIImplementationProvider;
protected Builder() { protected Builder() {
} }
/**
* Sets a provider of {@link UIImplementation}.
* Uses default provider if null is passed.
*/
public Builder setUIImplementationProvider(
@Nullable UIImplementationProvider uiImplementationProvider) {
mUIImplementationProvider = uiImplementationProvider;
return this;
}
/** /**
* Name of the JS bundle file to be loaded from application's raw assets. * Name of the JS bundle file to be loaded from application's raw assets.
*
* Example: {@code "index.android.js"} * Example: {@code "index.android.js"}
*/ */
public Builder setBundleAssetName(String bundleAssetName) { public Builder setBundleAssetName(String bundleAssetName) {
@ -231,6 +242,11 @@ public abstract class ReactInstanceManager {
mJSMainModuleName != null || mJSBundleFile != null, mJSMainModuleName != null || mJSBundleFile != null,
"Either MainModuleName or JS Bundle File needs to be provided"); "Either MainModuleName or JS Bundle File needs to be provided");
if (mUIImplementationProvider == null) {
// create default UIImplementationProvider if the provided one is null.
mUIImplementationProvider = new UIImplementationProvider();
}
return new ReactInstanceManagerImpl( return new ReactInstanceManagerImpl(
Assertions.assertNotNull( Assertions.assertNotNull(
mApplication, mApplication,
@ -240,7 +256,8 @@ public abstract class ReactInstanceManager {
mPackages, mPackages,
mUseDeveloperSupport, mUseDeveloperSupport,
mBridgeIdleDebugListener, mBridgeIdleDebugListener,
Assertions.assertNotNull(mInitialLifecycleState, "Initial lifecycle state was not set")); Assertions.assertNotNull(mInitialLifecycleState, "Initial lifecycle state was not set"),
mUIImplementationProvider);
} }
} }
} }

View File

@ -52,6 +52,7 @@ import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.AppRegistry; import com.facebook.react.uimanager.AppRegistry;
import com.facebook.react.uimanager.ReactNative; import com.facebook.react.uimanager.ReactNative;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
@ -95,6 +96,7 @@ import com.facebook.systrace.Systrace;
private String mSourceUrl; private String mSourceUrl;
private @Nullable Activity mCurrentActivity; private @Nullable Activity mCurrentActivity;
private volatile boolean mHasStartedCreatingInitialContext = false; private volatile boolean mHasStartedCreatingInitialContext = false;
private final UIImplementationProvider mUIImplementationProvider;
private final ReactInstanceDevCommandsHandler mDevInterface = private final ReactInstanceDevCommandsHandler mDevInterface =
new ReactInstanceDevCommandsHandler() { new ReactInstanceDevCommandsHandler() {
@ -189,7 +191,8 @@ import com.facebook.systrace.Systrace;
List<ReactPackage> packages, List<ReactPackage> packages,
boolean useDeveloperSupport, boolean useDeveloperSupport,
@Nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener, @Nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener,
LifecycleState initialLifecycleState) { LifecycleState initialLifecycleState,
UIImplementationProvider uiImplementationProvider) {
initializeSoLoaderIfNecessary(applicationContext); initializeSoLoaderIfNecessary(applicationContext);
mApplicationContext = applicationContext; mApplicationContext = applicationContext;
@ -208,6 +211,7 @@ import com.facebook.systrace.Systrace;
useDeveloperSupport); useDeveloperSupport);
mBridgeIdleDebugListener = bridgeIdleDebugListener; mBridgeIdleDebugListener = bridgeIdleDebugListener;
mLifecycleState = initialLifecycleState; mLifecycleState = initialLifecycleState;
mUIImplementationProvider = uiImplementationProvider;
} }
@Override @Override
@ -597,7 +601,7 @@ import com.facebook.systrace.Systrace;
"createAndProcessCoreModulesPackage"); "createAndProcessCoreModulesPackage");
try { try {
CoreModulesPackage coreModulesPackage = CoreModulesPackage coreModulesPackage =
new CoreModulesPackage(this, mBackBtnHandler); new CoreModulesPackage(this, mBackBtnHandler, mUIImplementationProvider);
processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);
} finally { } finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);

View File

@ -0,0 +1,24 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.uimanager;
import java.util.List;
import com.facebook.react.bridge.ReactApplicationContext;
/**
* Provides UIImplementation to use in {@link UIManagerModule}.
*/
public class UIImplementationProvider {
public UIImplementation createUIImplementation(
ReactApplicationContext reactContext,
List<ViewManager> viewManagers) {
return new UIImplementation(reactContext, viewManagers);
}
}

View File

@ -78,15 +78,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
private int mNextRootViewTag = 1; private int mNextRootViewTag = 1;
private int mBatchId = 0; private int mBatchId = 0;
/**
* This contructor is temporarily here to workaround Sandcastle error.
*/
public UIManagerModule(
ReactApplicationContext reactContext,
List<ViewManager> viewManagerList) {
this(reactContext, viewManagerList, new UIImplementation(reactContext, viewManagerList));
}
public UIManagerModule( public UIManagerModule(
ReactApplicationContext reactContext, ReactApplicationContext reactContext,
List<ViewManager> viewManagerList, List<ViewManager> viewManagerList,