Re-introduce UIImplementationProvider

Summary: UIImplementationProvider was removed as part of D8650376, this was a breaking change that caused problems in OSS. This diff introduces the concept of a deprecated UIImplementationProvider again to allow OSS community to upgrade to latest version of RN.

Reviewed By: achen1

Differential Revision: D10456317

fbshipit-source-id: 6817629524f927dfcb5ebc054dbfd983877b7606
This commit is contained in:
David Vacca 2018-10-20 11:24:55 -07:00 committed by Facebook Github Bot
parent 0bf520a821
commit b002df945b
6 changed files with 109 additions and 3 deletions

View File

@ -26,6 +26,7 @@ import com.facebook.react.modules.core.Timing;
import com.facebook.react.modules.debug.SourceCodeModule;
import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.systrace.Systrace;
@ -59,6 +60,7 @@ import javax.inject.Provider;
CoreModulesPackage(
ReactInstanceManager reactInstanceManager,
DefaultHardwareBackBtnHandler hardwareBackBtnHandler,
@Nullable UIImplementationProvider uiImplementationProvider,
boolean lazyViewManagersEnabled,
int minTimeLeftInFrameForNonBatchedOperationMs) {
mReactInstanceManager = reactInstanceManager;

View File

@ -81,6 +81,7 @@ import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
import com.facebook.react.modules.fabric.ReactFabric;
import com.facebook.react.packagerconnection.RequestHandler;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
@ -200,6 +201,7 @@ public class ReactInstanceManager {
boolean useDeveloperSupport,
@Nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener,
LifecycleState initialLifecycleState,
@Nullable UIImplementationProvider mUIImplementationProvider,
NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler,
@Nullable RedBoxHandler redBoxHandler,
boolean lazyViewManagersEnabled,
@ -250,6 +252,7 @@ public class ReactInstanceManager {
ReactInstanceManager.this.invokeDefaultOnBackPressed();
}
},
mUIImplementationProvider,
lazyViewManagersEnabled,
minTimeLeftInFrameForNonBatchedOperationMs));
if (mUseDeveloperSupport) {

View File

@ -22,6 +22,7 @@ import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.jscexecutor.JSCExecutorFactory;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.packagerconnection.RequestHandler;
import com.facebook.react.uimanager.UIImplementationProvider;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -41,6 +42,7 @@ public class ReactInstanceManagerBuilder {
private @Nullable Application mApplication;
private boolean mUseDeveloperSupport;
private @Nullable LifecycleState mInitialLifecycleState;
private @Nullable UIImplementationProvider mUIImplementationProvider;
private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private @Nullable Activity mCurrentActivity;
private @Nullable DefaultHardwareBackBtnHandler mDefaultHardwareBackBtnHandler;
@ -56,6 +58,16 @@ public class ReactInstanceManagerBuilder {
/* package protected */ ReactInstanceManagerBuilder() {
}
/**
* Sets a provider of {@link UIImplementation}.
* Uses default provider if null is passed.
*/
public ReactInstanceManagerBuilder setUIImplementationProvider(
@Nullable UIImplementationProvider uiImplementationProvider) {
mUIImplementationProvider = uiImplementationProvider;
return this;
}
public ReactInstanceManagerBuilder setJSIModulesPackage(
@Nullable JSIModulePackage jsiModulePackage) {
mJSIModulesPackage = jsiModulePackage;
@ -242,6 +254,11 @@ public class ReactInstanceManagerBuilder {
mJSMainModulePath != null || mJSBundleAssetUrl != null || mJSBundleLoader != null,
"Either MainModulePath or JS Bundle File needs to be provided");
if (mUIImplementationProvider == null) {
// create default UIImplementationProvider if the provided one is null.
mUIImplementationProvider = new UIImplementationProvider();
}
// We use the name of the device and the app for debugging & metrics
String appName = mApplication.getPackageName();
String deviceName = getFriendlyDeviceName();
@ -262,6 +279,7 @@ public class ReactInstanceManagerBuilder {
mUseDeveloperSupport,
mBridgeIdleDebugListener,
Assertions.assertNotNull(mInitialLifecycleState, "Initial lifecycle state was not set"),
mUIImplementationProvider,
mNativeModuleCallExceptionHandler,
mRedBoxHandler,
mLazyViewManagersEnabled,

View File

@ -15,6 +15,7 @@ import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.ReactMarkerConstants;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.devsupport.RedBoxHandler;
import com.facebook.react.uimanager.UIImplementationProvider;
import java.util.List;
import javax.annotation.Nullable;
@ -70,6 +71,7 @@ public abstract class ReactNativeHost {
.setUseDeveloperSupport(getUseDeveloperSupport())
.setRedBoxHandler(getRedBoxHandler())
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
.setUIImplementationProvider(getUIImplementationProvider())
.setJSIModulesPackage(getJSIModulePackage())
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
@ -107,6 +109,16 @@ public abstract class ReactNativeHost {
return mApplication;
}
/**
* Get the {@link UIImplementationProvider} to use. Override this method if you want to use a
* custom UI implementation.
*
* Note: this is very advanced functionality, in 99% of cases you don't need to override this.
*/
protected UIImplementationProvider getUIImplementationProvider() {
return new UIImplementationProvider();
}
protected @Nullable
JSIModulePackage getJSIModulePackage() {
return null;

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.events.EventDispatcher;
import java.util.List;
/**
* Provides UIImplementation to use in {@link UIManagerModule}.
*/
@Deprecated
public class UIImplementationProvider {
public UIImplementation createUIImplementation(
ReactApplicationContext reactContext,
UIManagerModule.ViewManagerResolver viewManagerResolver,
EventDispatcher eventDispatcher,
int minTimeLeftInFrameForNonBatchedOperationMs) {
return new UIImplementation(
reactContext,
viewManagerResolver,
eventDispatcher,
minTimeLeftInFrameForNonBatchedOperationMs);
}
public UIImplementation createUIImplementation(
ReactApplicationContext reactContext,
List<ViewManager> viewManagerList,
EventDispatcher eventDispatcher,
int minTimeLeftInFrameForNonBatchedOperationMs) {
return new UIImplementation(
reactContext,
viewManagerList,
eventDispatcher,
minTimeLeftInFrameForNonBatchedOperationMs);
}
}

View File

@ -116,21 +116,47 @@ public class UIManagerModule extends ReactContextBaseJavaModule
private final MemoryTrimCallback mMemoryTrimCallback = new MemoryTrimCallback();
private final List<UIManagerModuleListener> mListeners = new ArrayList<>();
private @Nullable Map<String, WritableMap> mViewManagerConstantsCache;
volatile private int mViewManagerConstantsCacheSize;
private volatile int mViewManagerConstantsCacheSize;
private int mBatchId = 0;
@SuppressWarnings("deprecated")
public UIManagerModule(
ReactApplicationContext reactContext,
ViewManagerResolver viewManagerResolver,
int minTimeLeftInFrameForNonBatchedOperationMs) {
this(
reactContext,
viewManagerResolver,
new UIImplementationProvider(),
minTimeLeftInFrameForNonBatchedOperationMs);
}
@SuppressWarnings("deprecated")
public UIManagerModule(
ReactApplicationContext reactContext,
List<ViewManager> viewManagersList,
int minTimeLeftInFrameForNonBatchedOperationMs) {
this(
reactContext,
viewManagersList,
new UIImplementationProvider(),
minTimeLeftInFrameForNonBatchedOperationMs);
}
@Deprecated
public UIManagerModule(
ReactApplicationContext reactContext,
ViewManagerResolver viewManagerResolver,
UIImplementationProvider uiImplementationProvider,
int minTimeLeftInFrameForNonBatchedOperationMs) {
super(reactContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
mEventDispatcher = new EventDispatcher(reactContext);
mModuleConstants = createConstants(viewManagerResolver);
mCustomDirectEvents = UIManagerModuleConstants.getDirectEventTypeConstants();
mUIImplementation =
new UIImplementation(
uiImplementationProvider.createUIImplementation(
reactContext,
viewManagerResolver,
mEventDispatcher,
@ -139,9 +165,11 @@ public class UIManagerModule extends ReactContextBaseJavaModule
reactContext.addLifecycleEventListener(this);
}
@Deprecated
public UIManagerModule(
ReactApplicationContext reactContext,
List<ViewManager> viewManagersList,
UIImplementationProvider uiImplementationProvider,
int minTimeLeftInFrameForNonBatchedOperationMs) {
super(reactContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
@ -149,7 +177,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule
mCustomDirectEvents = MapBuilder.newHashMap();
mModuleConstants = createConstants(viewManagersList, null, mCustomDirectEvents);
mUIImplementation =
new UIImplementation(
uiImplementationProvider.createUIImplementation(
reactContext,
viewManagersList,
mEventDispatcher,
@ -157,6 +185,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule
reactContext.addLifecycleEventListener(this);
}
/**
* This method gives an access to the {@link UIImplementation} object that can be used to execute
* operations on the view hierarchy.